From: Jeremy Bícha Date: Mon, 5 Aug 2024 15:43:49 +0000 (-0400) Subject: New upstream version 47~beta X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~226^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=46867cfa970edc703197cfaa2b442c580bdad3a7;p=gnome-shell.git New upstream version 47~beta --- 46867cfa970edc703197cfaa2b442c580bdad3a7 diff --cc data/theme/gnome-shell-dark.css index 780890a3d,000000000..6c873d7e8 mode 100644,000000..100644 --- a/data/theme/gnome-shell-dark.css +++ b/data/theme/gnome-shell-dark.css @@@ -1,3110 -1,0 +1,3219 @@@ +/* This stylesheet is generated, DO NOT EDIT */ +/* Copyright 2009, 2015 Red Hat, Inc. + * + * Portions adapted from Mx's data/style/default.css + * Copyright 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* Global Values */ +stage { + font-size: 1em; + color: #ffffff; } + +/* Common Stylings */ +#dash .dash-item-container .show-apps, +#dash .dash-item-container .overview-tile, +#dash .dash-item-container .grid-search-result { + background: none; + box-shadow: none; + border: none; + border-radius: 0; + padding: 0; + margin: 0; } + +.app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result, .app-folder, .overview-tile, .grid-search-result, #dash .dash-item-container .show-apps .overview-icon, +#dash .dash-item-container .overview-tile .overview-icon, +#dash .dash-item-container .grid-search-result .overview-icon, .list-search-result, .search-provider-icon, .switcher-list .item-box { + border-radius: 16px; + padding: 6px; + spacing: 6px; + text-align: center; + transition-duration: 100ms; } + +.login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item, .login-dialog-not-listed-button, .unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, - .unlock-dialog .screenshot-ui-show-pointer-button, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, ++.unlock-dialog .screenshot-ui-show-pointer-button, #LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + border-radius: 8px; + padding: 3px 24px; + font-weight: bold; + transition: border-width 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + color: #ffffff; - background-color: #474747; } ++ background-color: st-mix(#ffffff, #353535, 9%); } + .icon-button:focus, .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus, .screenshot-ui-show-pointer-button:focus, .message .message-header .message-expand-button:focus, + .message .message-header .message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } + .icon-button:focus:hover, .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .message .message-header .message-expand-button:focus:hover, + .message .message-header .message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button:focus:hover { - background-color: #505459; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } + .icon-button:hover, .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover, .screenshot-ui-show-pointer-button:hover, .message .message-header .message-expand-button:hover, + .message .message-header .message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button:hover { + color: #ffffff; - background-color: #515151; } ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 4%); } + .icon-button:insensitive, .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive, .screenshot-ui-show-pointer-button:insensitive, .message .message-header .message-expand-button:insensitive, + .message .message-header .message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #3f3f3f; } ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #353535, 9%), 3%); } + .icon-button:selected, .login-dialog-button.cancel-button:selected, .login-dialog-button.switch-user-button:selected, .login-dialog-button.login-dialog-session-list-button:selected, .screenshot-ui-show-pointer-button:selected, .message .message-header .message-expand-button:selected, + .message .message-header .message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button:selected, .icon-button:active, .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active, .screenshot-ui-show-pointer-button:active, .message .message-header .message-expand-button:active, + .message .message-header .message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button:active { + color: #ffffff; - background-color: #5e5e5e; } ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 9%); } + .icon-button:selected:hover, .login-dialog-button.cancel-button:selected:hover, .login-dialog-button.switch-user-button:selected:hover, .login-dialog-button.login-dialog-session-list-button:selected:hover, .screenshot-ui-show-pointer-button:selected:hover, .message .message-header .message-expand-button:selected:hover, + .message .message-header .message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button:selected:hover, .icon-button:active:hover, .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover, .screenshot-ui-show-pointer-button:active:hover, .message .message-header .message-expand-button:active:hover, + .message .message-header .message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button:active:hover { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 4%); } + .icon-button:selected:focus, .login-dialog-button.cancel-button:selected:focus, .login-dialog-button.switch-user-button:selected:focus, .login-dialog-button.login-dialog-session-list-button:selected:focus, .screenshot-ui-show-pointer-button:selected:focus, .message .message-header .message-expand-button:selected:focus, + .message .message-header .message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button:selected:focus, .icon-button:active:focus, .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus, .screenshot-ui-show-pointer-button:active:focus, .message .message-header .message-expand-button:active:focus, + .message .message-header .message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button:active:focus { - background-color: #5c6065; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 5%); } + .icon-button:checked, .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked, .screenshot-ui-show-pointer-button:checked, .message .message-header .message-expand-button:checked, + .message .message-header .message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button:checked { + color: #ffffff; - background-color: #5b5b5b; } ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 8%); } + .icon-button:checked:hover, .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .message .message-header .message-expand-button:checked:hover, + .message .message-header .message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button:checked:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 4%); } + .icon-button:checked:active, .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active, .screenshot-ui-show-pointer-button:checked:active, .message .message-header .message-expand-button:checked:active, + .message .message-header .message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button:checked:active { - background-color: #727272; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 9%); } + +.calendar .calendar-day-heading, .calendar .calendar-day, .calendar .calendar-month-header .calendar-month-label, .icon-button.flat, .flat.login-dialog-button.cancel-button, .flat.login-dialog-button.switch-user-button, .flat.login-dialog-button.login-dialog-session-list-button, .flat.screenshot-ui-show-pointer-button, .message .message-header .flat.message-expand-button, +.message .message-header .flat.message-close-button, .calendar .calendar-month-header .pager-button, .button.flat { + color: #ffffff; + background-color: #353535; } + .calendar .calendar-day-heading:focus, .calendar .calendar-day:focus, .calendar .calendar-month-header .calendar-month-label:focus, .icon-button.flat:focus, .flat.login-dialog-button.cancel-button:focus, .flat.login-dialog-button.switch-user-button:focus, .flat.login-dialog-button.login-dialog-session-list-button:focus, .flat.screenshot-ui-show-pointer-button:focus, .message .message-header .flat.message-expand-button:focus, + .message .message-header .flat.message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button.flat:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(53, 74, 100, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(53, 53, 53, 0.25), 5%); } + .calendar .calendar-day-heading:focus:hover, .calendar .calendar-day:focus:hover, .calendar .calendar-month-header .calendar-month-label:focus:hover, .icon-button.flat:focus:hover, .flat.login-dialog-button.cancel-button:focus:hover, .flat.login-dialog-button.switch-user-button:focus:hover, .flat.login-dialog-button.login-dialog-session-list-button:focus:hover, .flat.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .flat.message-expand-button:focus:hover, + .message .message-header .flat.message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button.flat:focus:hover { - background-color: #464a4e; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 7%), 5%); } + .calendar .calendar-day-heading:hover, .calendar .calendar-day:hover, .calendar .calendar-month-header .calendar-month-label:hover, .icon-button.flat:hover, .flat.login-dialog-button.cancel-button:hover, .flat.login-dialog-button.switch-user-button:hover, .flat.login-dialog-button.login-dialog-session-list-button:hover, .flat.screenshot-ui-show-pointer-button:hover, .message .message-header .flat.message-expand-button:hover, + .message .message-header .flat.message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button.flat:hover { + color: #ffffff; - background-color: #474747; } ++ background-color: st-lighten(#353535, 7%); } + .calendar .calendar-day-heading:insensitive, .calendar .calendar-day:insensitive, .calendar .calendar-month-header .calendar-month-label:insensitive, .icon-button.flat:insensitive, .flat.login-dialog-button.cancel-button:insensitive, .flat.login-dialog-button.switch-user-button:insensitive, .flat.login-dialog-button.login-dialog-session-list-button:insensitive, .flat.screenshot-ui-show-pointer-button:insensitive, .message .message-header .flat.message-expand-button:insensitive, + .message .message-header .flat.message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button.flat:insensitive { - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #353535; } + .calendar .calendar-day-heading:selected, .calendar .calendar-day:selected, .calendar .calendar-month-header .calendar-month-label:selected, .icon-button.flat:selected, .flat.login-dialog-button.cancel-button:selected, .flat.login-dialog-button.switch-user-button:selected, .flat.login-dialog-button.login-dialog-session-list-button:selected, .flat.screenshot-ui-show-pointer-button:selected, .message .message-header .flat.message-expand-button:selected, + .message .message-header .flat.message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button.flat:selected, .calendar .calendar-day-heading:active, .calendar .calendar-day:active, .calendar .calendar-month-header .calendar-month-label:active, .icon-button.flat:active, .flat.login-dialog-button.cancel-button:active, .flat.login-dialog-button.switch-user-button:active, .flat.login-dialog-button.login-dialog-session-list-button:active, .flat.screenshot-ui-show-pointer-button:active, .message .message-header .flat.message-expand-button:active, + .message .message-header .flat.message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button.flat:active { + color: #ffffff; - background-color: #4c4c4c; } ++ background-color: st-lighten(#353535, 9%); } + .calendar .calendar-day-heading:selected:hover, .calendar .calendar-day:selected:hover, .calendar .calendar-month-header .calendar-month-label:selected:hover, .icon-button.flat:selected:hover, .flat.login-dialog-button.cancel-button:selected:hover, .flat.login-dialog-button.switch-user-button:selected:hover, .flat.login-dialog-button.login-dialog-session-list-button:selected:hover, .flat.screenshot-ui-show-pointer-button:selected:hover, .message .message-header .flat.message-expand-button:selected:hover, + .message .message-header .flat.message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button.flat:selected:hover, .calendar .calendar-day-heading:active:hover, .calendar .calendar-day:active:hover, .calendar .calendar-month-header .calendar-month-label:active:hover, .icon-button.flat:active:hover, .flat.login-dialog-button.cancel-button:active:hover, .flat.login-dialog-button.switch-user-button:active:hover, .flat.login-dialog-button.login-dialog-session-list-button:active:hover, .flat.screenshot-ui-show-pointer-button:active:hover, .message .message-header .flat.message-expand-button:active:hover, + .message .message-header .flat.message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button.flat:active:hover { - background-color: #5e5e5e; } ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } + .calendar .calendar-day-heading:selected:focus, .calendar .calendar-day:selected:focus, .calendar .calendar-month-header .calendar-month-label:selected:focus, .icon-button.flat:selected:focus, .flat.login-dialog-button.cancel-button:selected:focus, .flat.login-dialog-button.switch-user-button:selected:focus, .flat.login-dialog-button.login-dialog-session-list-button:selected:focus, .flat.screenshot-ui-show-pointer-button:selected:focus, .message .message-header .flat.message-expand-button:selected:focus, + .message .message-header .flat.message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button.flat:selected:focus, .calendar .calendar-day-heading:active:focus, .calendar .calendar-day:active:focus, .calendar .calendar-month-header .calendar-month-label:active:focus, .icon-button.flat:active:focus, .flat.login-dialog-button.cancel-button:active:focus, .flat.login-dialog-button.switch-user-button:active:focus, .flat.login-dialog-button.login-dialog-session-list-button:active:focus, .flat.screenshot-ui-show-pointer-button:active:focus, .message .message-header .flat.message-expand-button:active:focus, + .message .message-header .flat.message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button.flat:active:focus { - background-color: #4b4f53; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } + .calendar .calendar-day-heading:checked, .calendar .calendar-day:checked, .calendar .calendar-month-header .calendar-month-label:checked, .icon-button.flat:checked, .flat.login-dialog-button.cancel-button:checked, .flat.login-dialog-button.switch-user-button:checked, .flat.login-dialog-button.login-dialog-session-list-button:checked, .flat.screenshot-ui-show-pointer-button:checked, .message .message-header .flat.message-expand-button:checked, + .message .message-header .flat.message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button.flat:checked { + color: #ffffff; - background-color: #494949; } ++ background-color: st-lighten(#353535, 8%); } + .calendar .calendar-day-heading:checked:hover, .calendar .calendar-day:checked:hover, .calendar .calendar-month-header .calendar-month-label:checked:hover, .icon-button.flat:checked:hover, .flat.login-dialog-button.cancel-button:checked:hover, .flat.login-dialog-button.switch-user-button:checked:hover, .flat.login-dialog-button.login-dialog-session-list-button:checked:hover, .flat.screenshot-ui-show-pointer-button:checked:hover, .message .message-header .flat.message-expand-button:checked:hover, + .message .message-header .flat.message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button.flat:checked:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 7%); } + .calendar .calendar-day-heading:checked:active, .calendar .calendar-day:checked:active, .calendar .calendar-month-header .calendar-month-label:checked:active, .icon-button.flat:checked:active, .flat.login-dialog-button.cancel-button:checked:active, .flat.login-dialog-button.switch-user-button:checked:active, .flat.login-dialog-button.login-dialog-session-list-button:checked:active, .flat.screenshot-ui-show-pointer-button:checked:active, .message .message-header .flat.message-expand-button:checked:active, + .message .message-header .flat.message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button.flat:checked:active { - background-color: #606060; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 9%); } + +.keyboard-brightness-level .button:checked, .quick-menu-toggle .quick-toggle-arrow:checked, .quick-toggle:checked, .calendar .calendar-day.calendar-today, .icon-button.default, .default.login-dialog-button.cancel-button, .default.login-dialog-button.switch-user-button, .default.login-dialog-button.login-dialog-session-list-button, .default.screenshot-ui-show-pointer-button, .message .message-header .default.message-expand-button, +.message .message-header .default.message-close-button, .calendar .calendar-month-header .default.pager-button, .button.default { - color: #ffffff; - background-color: #3584e4; } ++ color: -st-accent-fg-color; ++ background-color: -st-accent-color; } + .keyboard-brightness-level .button:focus:checked, .quick-menu-toggle .quick-toggle-arrow:focus:checked, .quick-toggle:focus:checked, .calendar .calendar-day.calendar-today:focus, .icon-button.default:focus, .default.login-dialog-button.cancel-button:focus, .default.login-dialog-button.switch-user-button:focus, .default.login-dialog-button.login-dialog-session-list-button:focus, .default.screenshot-ui-show-pointer-button:focus, .message .message-header .default.message-expand-button:focus, + .message .message-header .default.message-close-button:focus, .calendar .calendar-month-header .default.pager-button:focus, .button.default:focus { - color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - box-shadow: inset 0 0 0 2px #78aded !important; - background-color: #3584e4; } ++ color: -st-accent-fg-color; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ box-shadow: inset 0 0 0 2px st-lighten(-st-accent-color, 15%) !important; ++ background-color: st-mix(-st-accent-color, -st-accent-color, 5%); } + .keyboard-brightness-level .button:focus:hover:checked, .quick-menu-toggle .quick-toggle-arrow:focus:hover:checked, .quick-toggle:focus:hover:checked, .calendar .calendar-day.calendar-today:focus:hover, .icon-button.default:focus:hover, .default.login-dialog-button.cancel-button:focus:hover, .default.login-dialog-button.switch-user-button:focus:hover, .default.login-dialog-button.login-dialog-session-list-button:focus:hover, .default.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .default.message-expand-button:focus:hover, + .message .message-header .default.message-close-button:focus:hover, .calendar .calendar-month-header .default.pager-button:focus:hover, .button.default:focus:hover { - background-color: #468ee6; } ++ background-color: st-mix(-st-accent-color, st-lighten(-st-accent-color, 4%), 5%); } + .keyboard-brightness-level .button:hover:checked, .quick-menu-toggle .quick-toggle-arrow:hover:checked, .quick-toggle:hover:checked, .calendar .calendar-day.calendar-today:hover, .icon-button.default:hover, .default.login-dialog-button.cancel-button:hover, .default.login-dialog-button.switch-user-button:hover, .default.login-dialog-button.login-dialog-session-list-button:hover, .default.screenshot-ui-show-pointer-button:hover, .message .message-header .default.message-expand-button:hover, + .message .message-header .default.message-close-button:hover, .calendar .calendar-month-header .default.pager-button:hover, .button.default:hover { - color: #ffffff; - background-color: #478fe6; } ++ color: -st-accent-fg-color; ++ background-color: st-lighten(-st-accent-color, 4%); } + .keyboard-brightness-level .button:insensitive:checked, .quick-menu-toggle .quick-toggle-arrow:insensitive:checked, .quick-toggle:insensitive:checked, .calendar .calendar-day.calendar-today:insensitive, .icon-button.default:insensitive, .default.login-dialog-button.cancel-button:insensitive, .default.login-dialog-button.switch-user-button:insensitive, .default.login-dialog-button.login-dialog-session-list-button:insensitive, .default.screenshot-ui-show-pointer-button:insensitive, .message .message-header .default.message-expand-button:insensitive, + .message .message-header .default.message-close-button:insensitive, .calendar .calendar-month-header .default.pager-button:insensitive, .button.default:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #287ce2; } ++ color: st-transparentize(-st-accent-fg-color, 0.5); ++ background-color: st-darken(-st-accent-color, 3%); } + .keyboard-brightness-level .button:active:checked, .quick-menu-toggle .quick-toggle-arrow:active:checked, .quick-toggle:active:checked, .calendar .calendar-day.calendar-today:active, .icon-button.default:active, .default.login-dialog-button.cancel-button:active, .default.login-dialog-button.switch-user-button:active, .default.login-dialog-button.login-dialog-session-list-button:active, .default.screenshot-ui-show-pointer-button:active, .message .message-header .default.message-expand-button:active, + .message .message-header .default.message-close-button:active, .calendar .calendar-month-header .default.pager-button:active, .button.default:active { - color: #ffffff; - background-color: #5d9de9; } ++ color: -st-accent-fg-color; ++ background-color: st-lighten(-st-accent-color, 9%); } + .keyboard-brightness-level .button:active:hover:checked, .quick-menu-toggle .quick-toggle-arrow:active:hover:checked, .quick-toggle:active:hover:checked, .calendar .calendar-day.calendar-today:active:hover, .icon-button.default:active:hover, .default.login-dialog-button.cancel-button:active:hover, .default.login-dialog-button.switch-user-button:active:hover, .default.login-dialog-button.login-dialog-session-list-button:active:hover, .default.screenshot-ui-show-pointer-button:active:hover, .message .message-header .default.message-expand-button:active:hover, + .message .message-header .default.message-close-button:active:hover, .calendar .calendar-month-header .default.pager-button:active:hover, .button.default:active:hover { - background-color: #6fa8ec; } ++ background-color: st-lighten(st-lighten(-st-accent-color, 9%), 4%); } + .keyboard-brightness-level .button:active:focus:checked, .quick-menu-toggle .quick-toggle-arrow:active:focus:checked, .quick-toggle:active:focus:checked, .calendar .calendar-day.calendar-today:active:focus, .icon-button.default:active:focus, .default.login-dialog-button.cancel-button:active:focus, .default.login-dialog-button.switch-user-button:active:focus, .default.login-dialog-button.login-dialog-session-list-button:active:focus, .default.screenshot-ui-show-pointer-button:active:focus, .message .message-header .default.message-expand-button:active:focus, + .message .message-header .default.message-close-button:active:focus, .calendar .calendar-month-header .default.pager-button:active:focus, .button.default:active:focus { - background-color: #5b9be9; } ++ background-color: st-mix(-st-accent-color, st-lighten(-st-accent-color, 9%), 5%); } + +.popup-sub-menu .popup-menu-item, .popup-menu-item { + font-weight: normal; + spacing: 6px; + transition-duration: 100ms; + padding: 9px 12px; } + - .calendar, .datemenu-today-button, .lg-extension, .quick-toggle-menu, .message, .events-button, ++#LookingGlassExtensions .lg-extension, #LookingGlassWindows .lg-window, .calendar, .datemenu-today-button, .quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + border-radius: 12px; + padding: 0.818em; + margin: 4px; + background-color: #474747; + box-shadow: 0 1px 2px 0 transparent; + border: 1px solid transparent; } + - .lg-extension, .quick-toggle-menu, .message, .events-button, ++.quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + color: #ffffff; + background-color: #474747; } - .lg-extension:hover, .quick-toggle-menu:hover, .message:hover, .events-button:hover, ++ .quick-toggle-menu:hover, .message:hover, .events-button:hover, + .world-clocks-button:hover, + .weather-button:hover { + color: #ffffff; - background-color: #515151; } - .lg-extension:active, .quick-toggle-menu:active, .message:active, .events-button:active, ++ background-color: st-lighten(#474747, 4%); } ++ .quick-toggle-menu:active, .message:active, .events-button:active, + .world-clocks-button:active, + .weather-button:active { + color: #ffffff; - background-color: #5e5e5e; } - .lg-extension:active:hover, .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, ++ background-color: st-lighten(#474747, 9%); } ++ .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, + .world-clocks-button:active:hover, + .weather-button:active:hover { - background-color: #686868; } - .lg-extension:active:focus, .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, ++ background-color: st-lighten(st-lighten(#474747, 9%), 4%); } ++ .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, + .world-clocks-button:active:focus, + .weather-button:active:focus { - background-color: #5c5f64; } - .lg-extension:focus, .quick-toggle-menu:focus, .message:focus, .events-button:focus, ++ background-color: st-mix(-st-accent-color, st-lighten(#474747, 9%), 5%); } ++ .quick-toggle-menu:focus, .message:focus, .events-button:focus, + .world-clocks-button:focus, + .weather-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4e; } - .lg-extension:focus:hover, .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #474747, 5%); } ++ .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, + .world-clocks-button:focus:hover, + .weather-button:focus:hover { - background-color: #4f5358; } - .lg-extension:insensitive, .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, ++ background-color: st-mix(-st-accent-color, st-lighten(#474747, 4%), 5%); } ++ .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, + .world-clocks-button:insensitive, + .weather-button:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #3f3f3f; } ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(#474747, 3%); } + +.calendar, .datemenu-today-button { + border: 1px solid transparent !important; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .calendar:insensitive, .datemenu-today-button:insensitive { + background-color: transparent !important; } + .calendar:hover, .datemenu-today-button:hover { + color: #ffffff; - background-color: #474747; } ++ background-color: st-lighten(#353535, 7%); } + .calendar:active, .datemenu-today-button:active { + color: #ffffff; - background-color: #4c4c4c; } ++ background-color: st-lighten(#353535, 9%); } + .calendar:active:hover, .datemenu-today-button:active:hover { - background-color: #5e5e5e; } ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } + .calendar:active:focus, .datemenu-today-button:active:focus { - background-color: #4b4f53; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } + .calendar:focus, .datemenu-today-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4e; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #474747, 5%); } + .calendar:focus:hover, .datemenu-today-button:focus:hover { - background-color: #4f5358; } ++ background-color: st-mix(-st-accent-color, st-lighten(#474747, 4%), 5%); } + .calendar:insensitive, .datemenu-today-button:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #3f3f3f; } ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(#474747, 3%); } + +.unlock-dialog .login-dialog-prompt-entry, .login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry, .lg-dialog StEntry, StEntry { + border-radius: 8px; + padding: 9px 9px; - selection-background-color: #3584e4; ++ selection-background-color: st-transparentize(-st-accent-color, 0.7); + selected-color: #ffffff; } + +StEntry { + background-color: #474747; + color: rgba(255, 255, 255, 0.7); } + StEntry:hover { + background-color: #515151; + color: #ffffff; } + StEntry:focus { - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #474747, 5%); + color: #ffffff; } + StEntry:insensitive { + background-color: #3f3f3f; + color: rgba(255, 255, 255, 0.5); } + StEntry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + - .modal-dialog .modal-dialog-linked-button, .notification-button { ++.notification-button, .message .message-header .message-expand-button, ++.message .message-header .message-close-button { ++ font-weight: bold; ++ padding: 6px 12px; ++ border-radius: 8px; ++ color: #ffffff; ++ background-color: rgba(255, 255, 255, 0.15); } ++ .notification-button:focus, .message .message-header .message-expand-button:focus, ++ .message .message-header .message-close-button:focus { ++ color: #ffffff; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.15), 5%); } ++ .notification-button:focus:hover, .message .message-header .message-expand-button:focus:hover, ++ .message .message-header .message-close-button:focus:hover { ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.3), 5%); } ++ .notification-button:hover, .message .message-header .message-expand-button:hover, ++ .message .message-header .message-close-button:hover { ++ color: #ffffff; ++ background-color: rgba(255, 255, 255, 0.3); } ++ .notification-button:active, .message .message-header .message-expand-button:active, ++ .message .message-header .message-close-button:active { ++ color: #ffffff; ++ background-color: rgba(255, 255, 255, 0.2); } ++ .notification-button:active:hover, .message .message-header .message-expand-button:active:hover, ++ .message .message-header .message-close-button:active:hover { ++ background-color: rgba(255, 255, 255, 0.2); } ++ .notification-button:active:focus, .message .message-header .message-expand-button:active:focus, ++ .message .message-header .message-close-button:active:focus { ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.2), 5%); } ++ .notification-button:checked, .message .message-header .message-expand-button:checked, ++ .message .message-header .message-close-button:checked { ++ color: #ffffff; ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 8%); } ++ .notification-button:checked:hover, .message .message-header .message-expand-button:checked:hover, ++ .message .message-header .message-close-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 4%); } ++ .notification-button:checked:active, .message .message-header .message-expand-button:checked:active, ++ .message .message-header .message-close-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 9%); } ++ .notification-button:insensitive, .message .message-header .message-expand-button:insensitive, ++ .message .message-header .message-close-button:insensitive { ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: rgba(255, 255, 255, 0.1); } ++ ++.modal-dialog .modal-dialog-linked-button { ++ font-weight: bold; + padding: 12px; - font-weight: bold !important; ++ border-radius: 12px; + color: #ffffff; + background-color: rgba(255, 255, 255, 0.1); } - .modal-dialog .modal-dialog-linked-button:ltr, .notification-button:ltr { - margin-right: 1px; } - .modal-dialog .modal-dialog-linked-button:rtl, .notification-button:rtl { - margin-left: 1px; } - .modal-dialog .modal-dialog-linked-button:focus, .notification-button:focus { ++ .modal-dialog .modal-dialog-linked-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(154, 194, 242, 0.145); } - .modal-dialog .modal-dialog-linked-button:focus:hover, .notification-button:focus:hover { - background-color: rgba(168, 202, 243, 0.1735); } - .modal-dialog .modal-dialog-linked-button:hover, .notification-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.1), 5%); } ++ .modal-dialog .modal-dialog-linked-button:focus:hover { ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.13), 5%); } ++ .modal-dialog .modal-dialog-linked-button:hover { + color: #ffffff; + background-color: rgba(255, 255, 255, 0.13); } - .modal-dialog .modal-dialog-linked-button:active, .notification-button:active { ++ .modal-dialog .modal-dialog-linked-button:active { + color: #ffffff; + background-color: rgba(255, 255, 255, 0.16); } - .modal-dialog .modal-dialog-linked-button:active:hover, .notification-button:active:hover { ++ .modal-dialog .modal-dialog-linked-button:active:hover { + background-color: rgba(255, 255, 255, 0.19); } - .modal-dialog .modal-dialog-linked-button:active:focus, .notification-button:active:focus { - background-color: rgba(179, 209, 245, 0.202); } - .modal-dialog .modal-dialog-linked-button:checked, .notification-button:checked { ++ .modal-dialog .modal-dialog-linked-button:active:focus { ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.16), 5%); } ++ .modal-dialog .modal-dialog-linked-button:checked { + color: #ffffff; - background-color: #5b5b5b; } - .modal-dialog .modal-dialog-linked-button:checked:hover, .notification-button:checked:hover { - background-color: #666666; } - .modal-dialog .modal-dialog-linked-button:checked:active, .notification-button:checked:active { - background-color: #727272; } - .modal-dialog .modal-dialog-linked-button:insensitive, .notification-button:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #3f3f3f; } - .modal-dialog .modal-dialog-linked-button:first-child:ltr, .notification-button:first-child:ltr { - border-radius: 0 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:ltr, .notification-button:last-child:ltr { - border-radius: 0 0 15px; - margin-right: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:rtl, .notification-button:first-child:rtl { - border-radius: 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:rtl, .notification-button:last-child:rtl { - border-radius: 0 0 0 15px; - margin-left: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:last-child, .notification-button:first-child:last-child { - border-radius: 0 0 15px 15px; - margin-left: 0 !important; - margin-right: 0 !important; } ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 8%); } ++ .modal-dialog .modal-dialog-linked-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 4%); } ++ .modal-dialog .modal-dialog-linked-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 9%); } ++ .modal-dialog .modal-dialog-linked-button:insensitive { ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #353535, 9%), 3%); } + +.dash-label, .window-caption, .screenshot-ui-tooltip { + background-color: rgba(0, 0, 0, 0.9); + border: 1px solid rgba(255, 255, 255, 0.1); + color: #ffffff; + border-radius: 999px; + padding: 6px 12px; + text-align: center; } + +/* General Typography */ - .login-dialog .user-widget.vertical .user-widget-label, - .unlock-dialog .user-widget.vertical .user-widget-label, .unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { ++.unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { + font-weight: 800; + font-size: 1.818em; } + - .conflicting-session-dialog-content .conflicting-session-dialog-title, .lg-debug-flags-header, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { ++.conflicting-session-dialog-content .conflicting-session-dialog-title, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { + font-weight: 800; + font-size: 1.364em; } + +.login-dialog .user-widget.horizontal .user-widget-label, +.unlock-dialog .user-widget.horizontal .user-widget-label, .quick-toggle-menu .header .title { + font-weight: 700; + font-size: 1.364em; } + - .login-dialog-auth-list-label, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { ++.login-dialog-auth-list-label, #LookingGlassDebugFlags .lg-debug-flags-header, #LookingGlassExtensions .lg-extensions-none, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { + font-weight: 700; + font-size: 1.182em; } + - .login-dialog-not-listed-label, .lg-extension-name, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { ++.login-dialog-not-listed-label, #LookingGlassExtensions .lg-extension .lg-extension-name, #LookingGlassWindows .lg-window .lg-window-name, #LookingGlassPropertyInspector .lg-obj-inspector-title, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { + font-weight: 700; + font-size: 1em; } + +.quick-toggle-menu .header .subtitle, .app-menu .popup-inactive-menu-item:first-child > StLabel { + font-weight: 700; + font-size: 0.818em; } + +.lg-completions-text, .caps-lock-warning-label, .background-app-item .subtitle, .quick-toggle StBoxLayout > .quick-toggle-subtitle, .screenshot-ui-type-button .icon-label-button-container, .prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label, .run-dialog .run-dialog-description, .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description, .message .message-header .message-header-content .event-time, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .events-button .events-box .events-list .event-box .event-time { + font-weight: 400; + font-size: 0.818em; } + +.weather-button .weather-box .weather-grid .weather-forecast-time, .calendar .calendar-week-number, .calendar .calendar-day-heading, .calendar .calendar-day { + font-weight: 400; + font-size: 0.818em; } + - #EvalBox { ++#LookingGlassDebugFlags .lg-debug-flag-button StLabel, #LookingGlassEvaluator .evaluator-results, .lg-dialog .actor-link { + font-family: monospace; } + +.unlock-dialog-clock .unlock-dialog-clock-time, #panel, .weather-button .weather-box .weather-grid .weather-forecast-temp, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .world-clocks-button .world-clocks-grid .world-clocks-time, .events-button .events-box .events-list .event-box .event-time, .calendar .calendar-day-heading, .calendar .calendar-day { + font-feature-settings: "tnum"; } + +/* OSD Elements */ +#LookingGlassDialog, .screenshot-ui-panel, .workspace-switcher, .switcher-list, .resize-popup, .osd-window { + color: #ffffff; + background-color: #353535; + border: 1px solid rgba(255, 255, 255, 0.02); + border-radius: 999px; + padding: 12px; } + +.lg-dialog StEntry { + background-color: #474747; + color: rgba(255, 255, 255, 0.7); } + .lg-dialog StEntry:hover { + background-color: #515151; + color: #ffffff; } + .lg-dialog StEntry:focus { - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #474747, 5%); + color: #ffffff; } + .lg-dialog StEntry:insensitive { + background-color: #3f3f3f; + color: rgba(255, 255, 255, 0.5); } + .lg-dialog StEntry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + - #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button { ++#LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button { + color: #ffffff; - background-color: #474747; } - #LookingGlassDialog .notebook-tab:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { ++ background-color: st-mix(#ffffff, #353535, 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } - #LookingGlassDialog .notebook-tab:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { - background-color: #505459; } - #LookingGlassDialog .notebook-tab:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { + color: #ffffff; - background-color: #515151; } - #LookingGlassDialog .notebook-tab:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { + color: #ffffff; - background-color: #5e5e5e; } - #LookingGlassDialog .notebook-tab:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { - background-color: #686868; } - #LookingGlassDialog .notebook-tab:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { - background-color: #5c6065; } - #LookingGlassDialog .notebook-tab:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { + color: #ffffff; - background-color: #5b5b5b; } - #LookingGlassDialog .notebook-tab:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { - background-color: #666666; } - #LookingGlassDialog .notebook-tab:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { - background-color: #727272; } - #LookingGlassDialog .notebook-tab:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #3f3f3f; } - - .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 8%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 8%), 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:insensitive, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:insensitive, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #353535, 9%), 3%); } ++ ++#LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { + color: #ffffff; + background-color: #353535; } - .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { ++ #LookingGlassDialog .notebook-tab:focus, .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(53, 74, 100, 0.2875); } - .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { - background-color: #464a4e; } - .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(53, 53, 53, 0.25), 5%); } ++ #LookingGlassDialog .notebook-tab:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 7%), 5%); } ++ #LookingGlassDialog .notebook-tab:hover, .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { + color: #ffffff; - background-color: #474747; } - .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { ++ background-color: st-lighten(#353535, 7%); } ++ #LookingGlassDialog .notebook-tab:active, .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { + color: #ffffff; - background-color: #4c4c4c; } - .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { - background-color: #5e5e5e; } - .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { - background-color: #4b4f53; } - .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { ++ background-color: st-lighten(#353535, 9%); } ++ #LookingGlassDialog .notebook-tab:active:hover, .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } ++ #LookingGlassDialog .notebook-tab:active:focus, .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } ++ #LookingGlassDialog .notebook-tab:checked, .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { + color: #ffffff; - background-color: #494949; } - .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { - background-color: #5b5b5b; } - .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { - background-color: #606060; } - .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { - color: rgba(255, 255, 255, 0.5); ++ background-color: st-lighten(#353535, 8%); } ++ #LookingGlassDialog .notebook-tab:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { ++ background-color: st-lighten(st-lighten(#353535, 8%), 7%); } ++ #LookingGlassDialog .notebook-tab:checked:active, .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { ++ background-color: st-lighten(st-lighten(#353535, 8%), 9%); } ++ #LookingGlassDialog .notebook-tab:insensitive, .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { ++ color: st-transparentize(#ffffff, 0.5); + background-color: #353535; } + +/* System Elements */ +.login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry { + background-color: #464646; + color: rgba(245, 245, 245, 0.7); } + .login-dialog .login-dialog-prompt-entry:hover, .app-folder-dialog .folder-name-container .folder-name-entry:hover, .search-entry:hover { + background-color: #505050; + color: whitesmoke; } + .login-dialog .login-dialog-prompt-entry:focus, .app-folder-dialog .folder-name-container .folder-name-entry:focus, .search-entry:focus { - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #45494e; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #464646, 5%); + color: whitesmoke; } + .login-dialog .login-dialog-prompt-entry:insensitive, .app-folder-dialog .folder-name-container .folder-name-entry:insensitive, .search-entry:insensitive { + background-color: #3e3e3e; + color: rgba(245, 245, 245, 0.5); } + .login-dialog .login-dialog-prompt-entry StLabel.hint-text, .app-folder-dialog .folder-name-container .folder-name-entry StLabel.hint-text, .search-entry StLabel.hint-text { + color: rgba(245, 245, 245, 0.7); } + +.login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button { + color: whitesmoke; - background-color: #464646; } ++ background-color: st-mix(whitesmoke, #353535, 9%); } + .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive { - color: rgba(245, 245, 245, 0.5); - background-color: #3e3e3e; } ++ color: st-transparentize(whitesmoke, 0.5); ++ background-color: st-darken(st-mix(whitesmoke, #353535, 9%), 3%); } + .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #45494e; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #353535, 9%), 5%); } + .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: #4f5358; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #353535, 9%), 4%), 5%); } + .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover { + color: whitesmoke; - background-color: #505050; } ++ background-color: st-lighten(st-mix(whitesmoke, #353535, 9%), 4%); } + .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active { + color: whitesmoke; - background-color: #5d5d5d; } ++ background-color: st-lighten(st-mix(whitesmoke, #353535, 9%), 9%); } + .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover { - background-color: #676767; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #353535, 9%), 9%), 4%); } + .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: #5b5f64; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #353535, 9%), 9%), 5%); } + .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked { + color: whitesmoke; - background-color: #5a5a5a; } ++ background-color: st-lighten(st-mix(whitesmoke, #353535, 9%), 8%); } + .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #656565; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #353535, 9%), 8%), 4%); } + .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #717171; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #353535, 9%), 8%), 9%); } + +/* Lockscreen Elements */ +.unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .calendar .calendar-month-header .pager-button, +.calendar .calendar-month-header .unlock-dialog .pager-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, +.unlock-dialog .screenshot-ui-show-pointer-button, +.unlock-dialog .login-dialog-button.cancel-button, +.unlock-dialog .login-dialog-button.switch-user-button, +.unlock-dialog .login-dialog-button.login-dialog-session-list-button { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.1); } + .unlock-dialog .button:focus, + .unlock-dialog .icon-button:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus, + .unlock-dialog .message .message-header .message-expand-button:focus, + .message .message-header .unlock-dialog .message-expand-button:focus, + .unlock-dialog .message .message-header .message-close-button:focus, + .message .message-header .unlock-dialog .message-close-button:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:focus, + .unlock-dialog .login-dialog-button.cancel-button:focus, + .unlock-dialog .login-dialog-button.switch-user-button:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(149, 189, 237, 0.145); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.1), 5%); } + .unlock-dialog .button:focus:hover, + .unlock-dialog .icon-button:focus:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus:hover, + .unlock-dialog .message .message-header .message-expand-button:focus:hover, + .message .message-header .unlock-dialog .message-expand-button:focus:hover, + .unlock-dialog .message .message-header .message-close-button:focus:hover, + .message .message-header .unlock-dialog .message-close-button:focus:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:focus:hover, + .unlock-dialog .login-dialog-button.cancel-button:focus:hover, + .unlock-dialog .login-dialog-button.switch-user-button:focus:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: rgba(162, 196, 238, 0.1735); } ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.13), 5%); } + .unlock-dialog .button:hover, + .unlock-dialog .icon-button:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:hover, + .unlock-dialog .message .message-header .message-expand-button:hover, + .message .message-header .unlock-dialog .message-expand-button:hover, + .unlock-dialog .message .message-header .message-close-button:hover, + .message .message-header .unlock-dialog .message-close-button:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:hover, + .unlock-dialog .login-dialog-button.cancel-button:hover, + .unlock-dialog .login-dialog-button.switch-user-button:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:hover { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.13); } + .unlock-dialog .button:active, + .unlock-dialog .icon-button:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:active, + .unlock-dialog .message .message-header .message-expand-button:active, + .message .message-header .unlock-dialog .message-expand-button:active, + .unlock-dialog .message .message-header .message-close-button:active, + .message .message-header .unlock-dialog .message-close-button:active, + .unlock-dialog .screenshot-ui-show-pointer-button:active, + .unlock-dialog .login-dialog-button.cancel-button:active, + .unlock-dialog .login-dialog-button.switch-user-button:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.16); } + .unlock-dialog .button:active:hover, + .unlock-dialog .icon-button:active:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:hover, + .unlock-dialog .message .message-header .message-expand-button:active:hover, + .message .message-header .unlock-dialog .message-expand-button:active:hover, + .unlock-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .unlock-dialog .message-close-button:active:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:active:hover, + .unlock-dialog .login-dialog-button.cancel-button:active:hover, + .unlock-dialog .login-dialog-button.switch-user-button:active:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:hover { + background-color: rgba(245, 245, 245, 0.19); } + .unlock-dialog .button:active:focus, + .unlock-dialog .icon-button:active:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:focus, + .unlock-dialog .message .message-header .message-expand-button:active:focus, + .message .message-header .unlock-dialog .message-expand-button:active:focus, + .unlock-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .unlock-dialog .message-close-button:active:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:active:focus, + .unlock-dialog .login-dialog-button.cancel-button:active:focus, + .unlock-dialog .login-dialog-button.switch-user-button:active:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: rgba(173, 202, 239, 0.202); } ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.16), 5%); } + .unlock-dialog .button:checked, + .unlock-dialog .icon-button:checked, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked, + .unlock-dialog .message .message-header .message-expand-button:checked, + .message .message-header .unlock-dialog .message-expand-button:checked, + .unlock-dialog .message .message-header .message-close-button:checked, + .message .message-header .unlock-dialog .message-close-button:checked, + .unlock-dialog .screenshot-ui-show-pointer-button:checked, + .unlock-dialog .login-dialog-button.cancel-button:checked, + .unlock-dialog .login-dialog-button.switch-user-button:checked, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked { + color: whitesmoke; - background-color: #5a5a5a; } ++ background-color: st-lighten(st-mix(whitesmoke, #353535, 9%), 8%); } + .unlock-dialog .button:checked:hover, + .unlock-dialog .icon-button:checked:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:hover, + .unlock-dialog .message .message-header .message-expand-button:checked:hover, + .message .message-header .unlock-dialog .message-expand-button:checked:hover, + .unlock-dialog .message .message-header .message-close-button:checked:hover, + .message .message-header .unlock-dialog .message-close-button:checked:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:hover, + .unlock-dialog .login-dialog-button.cancel-button:checked:hover, + .unlock-dialog .login-dialog-button.switch-user-button:checked:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #656565; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #353535, 9%), 8%), 4%); } + .unlock-dialog .button:checked:active, + .unlock-dialog .icon-button:checked:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:active, + .unlock-dialog .message .message-header .message-expand-button:checked:active, + .message .message-header .unlock-dialog .message-expand-button:checked:active, + .unlock-dialog .message .message-header .message-close-button:checked:active, + .message .message-header .unlock-dialog .message-close-button:checked:active, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:active, + .unlock-dialog .login-dialog-button.cancel-button:checked:active, + .unlock-dialog .login-dialog-button.switch-user-button:checked:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #717171; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #353535, 9%), 8%), 9%); } + .unlock-dialog .button:insensitive, + .unlock-dialog .icon-button:insensitive, + .unlock-dialog .calendar .calendar-month-header .pager-button:insensitive, + .calendar .calendar-month-header .unlock-dialog .pager-button:insensitive, + .unlock-dialog .message .message-header .message-expand-button:insensitive, + .message .message-header .unlock-dialog .message-expand-button:insensitive, + .unlock-dialog .message .message-header .message-close-button:insensitive, + .message .message-header .unlock-dialog .message-close-button:insensitive, + .unlock-dialog .screenshot-ui-show-pointer-button:insensitive, + .unlock-dialog .login-dialog-button.cancel-button:insensitive, + .unlock-dialog .login-dialog-button.switch-user-button:insensitive, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:insensitive { - color: rgba(245, 245, 245, 0.5); - background-color: #3e3e3e; } ++ color: st-transparentize(whitesmoke, 0.5); ++ background-color: st-darken(st-mix(whitesmoke, #353535, 9%), 3%); } + +.unlock-dialog .login-dialog-prompt-entry { + background-color: rgba(245, 245, 245, 0.1); + color: rgba(245, 245, 245, 0.7); } + .unlock-dialog .login-dialog-prompt-entry:hover { + background-color: rgba(255, 255, 255, 0.1); + color: whitesmoke; } + .unlock-dialog .login-dialog-prompt-entry:focus { - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(149, 189, 237, 0.145); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.1), 5%); + color: whitesmoke; + box-shadow: inset 0 0 0 2px rgba(245, 245, 245, 0.4) !important; - background-color: rgba(245, 245, 245, 0.115); } ++ background-color: st-mix(rgba(245, 245, 245, 0.4), rgba(245, 245, 245, 0.1), 5%); } + .unlock-dialog .login-dialog-prompt-entry:insensitive { + background-color: rgba(237, 237, 237, 0.1); + color: rgba(245, 245, 245, 0.5); } + .unlock-dialog .login-dialog-prompt-entry StLabel.hint-text { + color: rgba(245, 245, 245, 0.7); } + +/* WIDGETS */ +.shell-link { - color: #62a0ea; } ++ color: st-lighten(-st-accent-color, 20%); } + .shell-link:hover { - color: #8fbbf0; } ++ color: st-lighten(st-lighten(-st-accent-color, 20%), 10%); } + +.lowres-icon { + icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } + +.icon-dropshadow { + icon-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); } + +/* Entries */ +StEntry StIcon.capslock-warning { + icon-size: 1.091em; + warning-color: #f6d32d; + padding: 0 4px; } + +StEntry StIcon.peek-password { + icon-size: 1.091em; + padding: 0 4px; } + +StEntry StLabel.hint-text { + margin-left: 2px; } + +/* Buttons */ +.button { + min-height: 1.5em; } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button { + border-radius: 999px; + padding: 0.818em; + min-height: 1.091em; } + .icon-button StIcon, .login-dialog-button.cancel-button StIcon, .login-dialog-button.switch-user-button StIcon, .login-dialog-button.login-dialog-session-list-button StIcon, .screenshot-ui-show-pointer-button StIcon, .message .message-header .message-expand-button StIcon, + .message .message-header .message-close-button StIcon, .calendar .calendar-month-header .pager-button StIcon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + +/* Check Boxes */ +.check-box StBoxLayout { + spacing: .8em; } + +.check-box StBin { - width: 24px; - height: 24px; - background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); } ++ border-radius: 7px; ++ padding: 2px; } + +.check-box:focus StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); } ++ background-color: rgba(0, 0, 0, 0.01); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.65); } ++ ++.check-box StIcon { ++ icon-size: 14px; ++ padding: 1px; ++ color: transparent; ++ border-radius: 6px; ++ border: 2px solid rgba(255, 255, 255, 0.15); } ++ ++.check-box:hover StIcon { ++ border-color: rgba(255, 255, 255, 0.2); } ++ ++.check-box:active StIcon { ++ border-color: rgba(255, 255, 255, 0.3); } ++ ++.check-box:checked StIcon { ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; ++ border-color: transparent; } + - .check-box:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); } ++.check-box:checked:hover StIcon { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } + - .check-box:focus:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); } ++.check-box:checked:active StIcon { ++ background-color: st-darken(-st-accent-color, 7%); ++ color: st-darken(-st-accent-fg-color, 7%); } + +/* Switches */ +.toggle-switch { - color: #ffffff; - height: 26px; + width: 46px; - background-size: contain; - background-image: url("resource:///org/gnome/shell/theme/toggle-off.svg"); } - .toggle-switch:checked { - background-image: url("resource:///org/gnome/shell/theme/toggle-on.svg"); } ++ border-radius: 999px; ++ transition-duration: 100ms; ++ color: #ffffff; ++ background: rgba(255, 255, 255, 0.15); } ++ .toggle-switch:hover { ++ background: rgba(255, 255, 255, 0.2); } + .toggle-switch StIcon { + icon-size: 16px; } ++ .toggle-switch .handle { ++ margin: 3px; ++ width: 20px; ++ height: 20px; ++ border-radius: 999px; ++ background: #d7d7d7; ++ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); ++ transition-duration: 100ms; } ++ .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } ++ .toggle-switch:checked .handle { ++ background: white; } + +/* Slider */ +.slider { ++ color: #e8e8e8; + -barlevel-height: 4px; - -barlevel-background-color: rgba(255, 255, 255, 0.2); - -barlevel-border-width: 2px; - -barlevel-border-color: transparent; - -barlevel-active-background-color: #3584e4; - -barlevel-active-border-color: transparent; ++ -barlevel-background-color: rgba(255, 255, 255, 0.1); ++ -barlevel-active-background-color: -st-accent-color; + -barlevel-overdrive-color: #c01c28; - -barlevel-overdrive-border-color: transparent; + -barlevel-overdrive-separator-width: 1px; - -slider-handle-radius: 0.5455em; - -slider-handle-border-width: 0; - -slider-handle-border-color: transparent; } ++ -slider-handle-radius: 0.5455em; } ++ .slider:hover { ++ color: #ffffff; } + +/* Scrollbars */ +StScrollView.vfade { + -st-vfade-offset: 68px; } + +StScrollView.hfade { + -st-hfade-offset: 68px; } + +StScrollBar { + padding: 0; } + StScrollView StScrollBar { + min-width: 8px; + min-height: 8px; } + StScrollBar StBin#trough { + border-radius: 0; + background-color: transparent; } + StScrollBar StButton#vhandle, StScrollBar StButton#hhandle { + border-radius: 8px; + background-color: #717171; + border: 3px solid transparent; + transition: 500ms all ease; } + StScrollBar StButton#vhandle:hover, StScrollBar StButton#hhandle:hover { + background-color: #9a9a9a; } + StScrollBar StButton#vhandle:active, StScrollBar StButton#hhandle:active { + background-color: #868686; } + +/* Popovers/Menus */ +.popup-menu-boxpointer, .candidate-popup-boxpointer { + -arrow-rise: 6px; } + +.popup-menu { + min-width: 15em; + color: #ffffff; } + .popup-menu.panel-menu { + margin-bottom: 1.75em; } + +.popup-menu-content, .candidate-popup-content { + padding: 6px; + background-color: #353535; + border-radius: 20px; + border: 1px solid #424242; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); } + +.popup-menu-item { + background-color: transparent; + border-color: transparent; + box-shadow: none; + border-radius: 12px; } + .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-menu-item:focus, .popup-menu-item:hover { ++ .popup-menu-item:hover { + color: #ffffff; - background-color: #5d5d5d; } ++ background-color: st-lighten(st-mix(#ffffff, #424242, 9%), 4%); } + .popup-menu-item:active { + color: #ffffff; - background-color: #6a6a6a; } ++ background-color: st-lighten(st-mix(#ffffff, #424242, 9%), 9%); } + .popup-menu-item:active:hover { - background-color: #747474; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #424242, 9%), 9%), 4%); } + .popup-menu-item:active:focus { - background-color: #676b70; } - .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #424242, 9%), 9%), 5%); } ++ .popup-menu-item:selected, .popup-menu-item:checked { + color: #ffffff; - background-color: #676767; } - .popup-menu-item:checked:hover { - background-color: #727272; } - .popup-menu-item:checked:active { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-mix(#ffffff, #424242, 9%), 8%); } ++ .popup-menu-item:selected:hover, .popup-menu-item:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #424242, 9%), 8%), 4%); } ++ .popup-menu-item:selected:active, .popup-menu-item:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #424242, 9%), 8%), 9%); } + .popup-menu-item:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #4b4b4b; } ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #424242, 9%), 3%); } + .popup-menu-item:checked { + border-radius: 12px 12px 0 0 !important; } + .popup-menu-item .toggle-switch:ltr { + margin-left: 4px; } + .popup-menu-item .toggle-switch:rtl { + margin-right: 4px; } + +.popup-ornamented-menu-item:ltr { + padding-left: 6px; } + +.popup-ornamented-menu-item:rtl { + padding-right: 6px; } + +.popup-inactive-menu-item { + color: #ffffff; } + .popup-inactive-menu-item:insensitive { + color: #9a9a9a; } + +.popup-menu-arrow, +.popup-menu-icon { + icon-size: 1.091em; } + +.popup-sub-menu { + border-radius: 0 0 13px 13px; + margin-bottom: 6px; + border: 1px solid transparent; + background-color: #565656; } + .popup-sub-menu .popup-menu-item { + border-radius: 0; + border-top-width: 0; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .popup-sub-menu .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-sub-menu .popup-menu-item:focus, .popup-sub-menu .popup-menu-item:hover { ++ .popup-sub-menu .popup-menu-item:hover { + color: #ffffff; - background-color: #6f6f6f; } ++ background-color: st-lighten(st-mix(#ffffff, #565656, 9%), 4%); } + .popup-sub-menu .popup-menu-item:active { + color: #ffffff; - background-color: #7c7c7c; } ++ background-color: st-lighten(st-mix(#ffffff, #565656, 9%), 9%); } + .popup-sub-menu .popup-menu-item:active:hover { - background-color: #868686; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #565656, 9%), 9%), 4%); } + .popup-sub-menu .popup-menu-item:active:focus { - background-color: #787c81; } - .popup-sub-menu .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #565656, 9%), 9%), 5%); } ++ .popup-sub-menu .popup-menu-item:selected, .popup-sub-menu .popup-menu-item:checked { + color: #ffffff; - background-color: #797979; } - .popup-sub-menu .popup-menu-item:checked:hover { - background-color: #848484; } - .popup-sub-menu .popup-menu-item:checked:active { - background-color: #909090; } ++ background-color: st-lighten(st-mix(#ffffff, #565656, 9%), 8%); } ++ .popup-sub-menu .popup-menu-item:selected:hover, .popup-sub-menu .popup-menu-item:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #565656, 9%), 8%), 4%); } ++ .popup-sub-menu .popup-menu-item:selected:active, .popup-sub-menu .popup-menu-item:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #565656, 9%), 8%), 9%); } + .popup-sub-menu .popup-menu-item:insensitive { - color: rgba(255, 255, 255, 0.5); - background-color: #5d5d5d; } ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #565656, 9%), 3%); } + .popup-sub-menu .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; + border-bottom-width: 0; } + .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:hover, .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:focus { + border-radius: 0; } + .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; } + +.popup-menu-ornament { + icon-size: 1.091em !important; + width: 1.091em; } + +.popup-separator-menu-item { + border: none !important; } + .popup-separator-menu-item .popup-separator-menu-item-separator { + height: 1px; + background-color: rgba(255, 255, 255, 0.1); } + .popup-sub-menu .popup-separator-menu-item { + background-color: transparent; } + .popup-sub-menu .popup-separator-menu-item:ltr { + margin-right: 2.5em; } + .popup-sub-menu .popup-separator-menu-item:rtl { + margin-left: 2.5em; } + .popup-sub-menu .popup-separator-menu-item .popup-separator-menu-item-separator { + background-color: rgba(255, 255, 255, 0.1); } + +.background-menu { + -boxpointer-gap: 0px; + -arrow-rise: 0px; } + +.app-menu { + max-width: 27.25em; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:ltr { + margin-right: 8px; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:rtl { + margin-left: 8px; } + +/* Date/Time Menu */ +#calendarArea { + padding: 4px; } + +.datemenu-popover { + border-radius: 30px; } + +.datemenu-calendar-column { + spacing: 6px; } + .datemenu-calendar-column:ltr { + margin-left: 6px; } + .datemenu-calendar-column:rtl { + margin-right: 6px; } + .datemenu-calendar-column .datemenu-displays-box { + spacing: 6px; } + +.datemenu-today-button { + padding: 9px; } + .datemenu-today-button .day-label { + font-weight: bold; } + +.calendar { + margin-top: 0; + padding: 0; } + .calendar .calendar-month-header .calendar-change-month-back StIcon, + .calendar .calendar-month-header .calendar-change-month-forward StIcon { + icon-size: 1.091em; } + .calendar .calendar-month-header .calendar-month-label { + color: #ffffff !important; + padding: 8px 0; + width: 10em; + border-radius: 999px; + text-align: center; } + .calendar .calendar-month-header .pager-button { + height: 2.6em; + width: 2.6em; + padding: 0; } + .calendar .calendar-day { + border-radius: 999px; + height: 3em; + width: 3em; + margin: 2px; + padding: 0; + font-weight: bold; + text-align: center; } + .calendar .calendar-day.calendar-weekend { + color: #9a9a9a; } + .calendar .calendar-day.calendar-other-month { + color: rgba(255, 255, 255, 0.5); + font-weight: normal; } + .calendar .calendar-day.calendar-other-month.calendar-weekend { + color: rgba(255, 255, 255, 0.5); } + .calendar .calendar-day.calendar-today { - color: #ffffff !important; } ++ color: -st-accent-fg-color !important; } + .calendar .calendar-day.calendar-today.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg") !important; } + .calendar .calendar-day.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg"); + background-size: contain; } + .calendar .calendar-day-heading { + font-weight: bold; + text-align: center; + margin: 4px; + padding: 3px 6px; + border-radius: 8px; } + .calendar .calendar-week-number { + font-weight: bold; + font-feature-settings: "tnum"; + text-align: center; + margin: 6px; + padding: 0 6px; + border-radius: 4px; + background-color: rgba(154, 154, 154, 0.2); + color: #9a9a9a; } + +.events-button .events-box .events-title { + color: #9a9a9a; + padding-bottom: 6px; } + +.events-button .events-box .events-list { + spacing: 6px; } + .events-button .events-box .events-list .event-box { + spacing: 6px; + border-radius: 8px; } + .events-button .events-box .events-list .event-box .event-time { + color: #9a9a9a; } + .events-button .events-box .events-list .event-placeholder { + color: #9a9a9a; + font-style: italic; } + +.world-clocks-button .world-clocks-header { + color: #9a9a9a; } + .world-clocks-button .world-clocks-header.no-world-clocks { + color: #ffffff; } + +.world-clocks-button .world-clocks-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .world-clocks-button .world-clocks-grid .world-clocks-time { + font-weight: bold; } + .world-clocks-button .world-clocks-grid .world-clocks-time:ltr { + text-align: right; } + .world-clocks-button .world-clocks-grid .world-clocks-time:rtl { + text-align: left; } + .world-clocks-button .world-clocks-grid .world-clocks-timezone { + color: #9a9a9a; } + +.weather-button .weather-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box .weather-header { + color: #9a9a9a; } + .weather-button .weather-box .weather-header-box .weather-header.no-location { + color: #ffffff; } + .weather-button .weather-box .weather-header-box .weather-header.location { + font-weight: normal; } + .weather-button .weather-box .weather-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .weather-button .weather-box .weather-grid .weather-forecast-time { + padding-top: 6px; + padding-bottom: 6px; } + .weather-button .weather-box .weather-grid .weather-forecast-icon { + icon-size: 2.182em; + margin-bottom: 4px; } + .weather-button .weather-box .weather-grid .weather-forecast-temp { + font-weight: bold; } + +/* Message List */ +.message-list { + width: 29em; + border: solid rgba(255, 255, 255, 0.1); } + .message-list:ltr { + margin-left: 0; + margin-right: 4px; + padding-right: 6px; + border-right-width: 1px; } + .message-list:rtl { + margin-right: 0; + margin-left: 4px; + padding-left: 6px; + border-left-width: 1px; } + .message-list .message-list-placeholder { + color: rgba(255, 255, 255, 0.25); } + .message-list .message-list-placeholder > StIcon { + icon-size: 96px; + margin-bottom: 12px; + -st-icon-style: symbolic; } + +.message-list-sections { + spacing: 12px; } + .message-list-sections:ltr { + margin-right: 12px; } + .message-list-sections:rtl { + margin-left: 12px; } + +.message-list-section, +.message-list-section-list { + spacing: 12px; } + +.message-list-controls { + padding: 12px; + padding-bottom: 6px; + spacing: 6px; } + .message-list-controls .dnd-button { + border-width: 2px; + border-color: transparent; + border-radius: 32px; + border-style: solid; } + .message-list-controls .dnd-button:focus { - border-color: rgba(53, 132, 228, 0.6); } ++ border-color: st-transparentize(-st-accent-color, 0.4); } + +.message { - padding: 0; ++ padding: 6px; + margin: 0; + border-radius: 16px; } - .message:ltr { - padding-right: -2px; } - .message:rtl { - padding-left: -2px; } + .message .message-header { - padding: 0 0.409em; - margin: 6px; - margin-bottom: 0; + spacing: 6px; - color: #9a9a9a; } ++ color: #9a9a9a; ++ padding: 0 6px; } ++ .message .message-header:ltr { ++ padding-right: 4px; } ++ .message .message-header:rtl { ++ padding-left: 4px; } + .message .message-header .message-source-icon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + .message .message-header .message-header-content { + spacing: 6px; + min-height: 1.637em; + padding-bottom: 6px; } + .message .message-header .message-header-content .message-source-title { + font-weight: bold; } + .message .message-header .message-header-content .event-time { + color: #9a9a9a; + padding-bottom: 0.068em; } + .message .message-header .message-header-content .event-time:ltr { + text-align: right; } + .message .message-header .message-header-content .event-time:rtl { + text-align: left; } + .message .message-header .message-expand-button, + .message .message-header .message-close-button { ++ border-radius: 999px; + color: #ffffff; - background-color: rgba(255, 255, 255, 0.1); + padding: 4px; } - .message .message-header .message-expand-button:hover, - .message .message-header .message-close-button:hover { - background-color: rgba(255, 255, 255, 0.19); } - .message .message-header .message-expand-button:active, .message .message-header .message-expand-button:active:hover, - .message .message-header .message-close-button:active, - .message .message-header .message-close-button:active:hover { - background-color: rgba(255, 255, 255, 0.24); } - .message .message-header .message-expand-button:insensitive, - .message .message-header .message-close-button:insensitive { - background-color: rgba(255, 255, 255, 0.07); } + .message .message-header .message-expand-button { + padding: 6px; } + .message .message-header .message-expand-button:ltr { + margin-right: 6px; } + .message .message-header .message-expand-button:rtl { + margin-left: 6px; } + .message .message-box { + padding: 6px; - margin: 6px; + margin-top: 0; + spacing: 6px; } + .message .message-box .message-icon { + icon-size: 48px; } + .message .message-box .message-icon:ltr { + margin-right: 6px; } + .message .message-box .message-icon:rtl { + margin-left: 6px; } + .message .message-box .message-icon.message-themed-icon { + border-radius: 999px; + background-color: rgba(255, 255, 255, 0.07); + icon-size: 1.091em; + min-width: 48px; + min-height: 48px; } + .message .message-box:first-child { + margin-top: 12px; } + .message .message-box .message-content { + spacing: 4px; } + .message .message-box .message-content .message-title { + font-weight: bold; } ++ .message .message-action-bin { ++ padding: 4px; ++ spacing: 6px; } ++ .message .message-action-bin * { ++ margin: 0 4px; } ++ .message .message-action-bin *:first-child:ltr { ++ margin-left: 0; } ++ .message .message-action-bin *:first-child:rtl { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:ltr { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:rtl { ++ margin-left: 0; } + +.url-highlighter { - link-color: #62a0ea; } ++ link-color: st-lighten(-st-accent-color, 20%); } + +/* Media Controls */ +.message-media-control { + padding: 0 18px; + border-radius: 8px; + color: #ffffff; + border: 1px solid transparent; } + .message-media-control:hover { + background-color: #5b5b5b; + color: #ffffff; } + .message-media-control:active { + background-color: #606060; + color: #ffffff; } + .message-media-control:insensitive { + color: #a7a7a7; } + .message-media-control StIcon { + icon-size: 16px; } + +.media-message .message-icon { + border-radius: 8px !important; } + .media-message .message-icon.message-themed-icon { + icon-size: 32px !important; } + +.candidate-popup-content { + padding: 6px; + spacing: 6px; } + +.candidate-index { + padding: 0; + padding-right: 6px; + color: #9a9a9a; } + +.candidate-box { + padding: 6px 12px 6px 12px; + border-radius: 8px; } + .candidate-box:selected { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + .candidate-box:hover { + background-color: #4e4e4e; + color: white; } + +.candidate-page-button-box { + height: 2em; } + .vertical .candidate-page-button-box { + padding-top: 12px; } + .horizontal .candidate-page-button-box { + padding-left: 12px; } + +.candidate-page-button { + padding: 6px; } + .candidate-page-button StIcon { + icon-size: 16px; } + +.candidate-page-button-previous { + border-radius: 8px 0px 0px 8px; + border-right-width: 0; + box-shadow: none; } + +.candidate-page-button-next { + border-radius: 0px 8px 8px 0px; + box-shadow: none; } + +/* Notifications & Message Tray */ +.notification-banner { + min-height: 64px; + width: 34em; + box-shadow: 0 2px 4px 2px rgba(0, 0, 0, 0.2); + border-radius: 16px; + margin: 4px; } + +.notification-buttons-bin { + spacing: 0; } + +/* Modal Dialogs */ +.modal-dialog { + background-color: #353535; - border-radius: 16px; - box-shadow: inset 0 0 0 1px #424242; } ++ border-radius: 18px; ++ box-shadow: inset 0 0 0 1px #424242; ++ padding: 24px; } + .modal-dialog .modal-dialog-content-box { - margin: 32px 40px; + spacing: 32px; ++ margin-top: 8px; ++ margin-bottom: 16px; + max-width: 28em; } + +/* End Session Dialog */ +.end-session-dialog { - width: 30em; } ++ width: 24em; } + .end-session-dialog .end-session-dialog-battery-warning, + .end-session-dialog .dialog-list-title { + color: #f6d32d; } + +/* Message Dialog */ +.message-dialog-content { + spacing: 18px; } + .message-dialog-content .message-dialog-title { + text-align: center; } + .message-dialog-content .message-dialog-description { + text-align: center; } + +/* Dialog List */ +.dialog-list { + spacing: 18px; } + .dialog-list .dialog-list-title { + text-align: center; } + .dialog-list .dialog-list-scrollview { + max-height: 200px; } + .dialog-list .dialog-list-box { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-title { + font-weight: bold; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description { + color: #f2f2f2; } + +/* Run Dialog */ +.run-dialog .modal-dialog-content-box { + margin-top: 24px; + margin-bottom: 12px; } + +.run-dialog .run-dialog-entry { + width: 20em; } + +.run-dialog .run-dialog-description { + text-align: center; + color: #cccccc; } + +/* Password or Authentication Dialog */ +.prompt-dialog { + width: 28em; } + .prompt-dialog .modal-dialog-content-box { + margin-bottom: 24px; } + +.prompt-dialog-password-grid { + spacing-rows: 8px; + spacing-columns: 4px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry { + width: auto; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:ltr { + margin-left: 20px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:rtl { + margin-right: 20px; } + +.prompt-dialog-password-layout { + spacing: 8px; } + +.prompt-dialog-password-entry { + width: 20em; } + +.prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label { + text-align: center; } + +.prompt-dialog-error-label { + color: #f6d32d; } + +/* Polkit Dialog */ +.polkit-dialog-user-layout { + text-align: center; + spacing: 8px; + margin-bottom: 6px; } + .polkit-dialog-user-layout .polkit-dialog-user-root-label { + color: #f6d32d; } + +/* Audio selection dialog */ +.audio-device-selection-dialog .modal-dialog-content-box { + margin-bottom: 28px; } + +.audio-device-selection-dialog .audio-selection-box { + spacing: 20px; } + +.audio-selection-device { + border-radius: 16px; } + .audio-selection-device:hover, .audio-selection-device:focus { + background-color: #4e4e4e; } + .audio-selection-device:active { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.audio-selection-device-box { + padding: 20px; + spacing: 20px; } + +.audio-selection-device-icon { + icon-size: 64px; } + +/* Welcome dialog */ +.welcome-dialog-image { + background-image: url("resource:///org/gnome/shell/theme/gnome-shell-start.svg"); + background-size: contain; + /* Reasonable maximum dimensions */ + height: 300px; + width: 300px; } + +/* Access portal dialog */ +.access-dialog { + text-align: center; } + +/* OSD */ +.osd-window { + text-align: center; + font-weight: bold; + spacing: 12px; + padding: 12px 18px; + margin-bottom: 4em; } + .osd-window > * { + spacing: 8px; } + .osd-window StIcon { + icon-size: 32px; } + .osd-window StLabel:ltr { + margin-right: 6px; } + .osd-window StLabel:rtl { + margin-left: 6px; } + .osd-window .level { + margin-bottom: 4px; + min-width: 160px; + -barlevel-height: 6px; + -barlevel-background-color: rgba(255, 255, 255, 0.1); + -barlevel-active-background-color: #ffffff; + -barlevel-overdrive-color: #c01c28; + -barlevel-overdrive-separator-width: 3px; } + .osd-window .level:first-child { + margin-bottom: 0; } + .osd-window .level:ltr { + margin-right: 6px; } + .osd-window .level:rtl { + margin-left: 6px; } + +.osd-monitor-label { - background-color: #3584e4; - color: #ffffff; ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; + border-radius: 16px; + font-size: 3em; + font-weight: bold; + font-feature-settings: "tnum"; + margin: 12px; + padding: 12px; + text-align: center; + min-width: 1.5em; } + +/* Pad OSD */ +.pad-osd-window { + padding: 32px; + background-color: rgba(0, 0, 0, 0.8); } + .pad-osd-window .pad-osd-title-box { + spacing: 12px; } + .pad-osd-window .pad-osd-title-menu-box { + spacing: 6px; } + +.combo-box-label { + width: 15em; } + +/* App Switcher */ +.switcher-popup { + padding: 0; + spacing: 24px; } + +.switcher-list { + padding: 12px; + border-radius: 28px; + box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.2); } + .switcher-list .switcher-list-item-container { + spacing: 12px; } + .switcher-list .item-box { + color: #ffffff; + background-color: #353535; } + .switcher-list .item-box:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(53, 74, 100, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(53, 53, 53, 0.25), 5%); } + .switcher-list .item-box:focus:hover { - background-color: #464a4e; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 7%), 5%); } + .switcher-list .item-box:hover { + color: #ffffff; - background-color: #474747; } ++ background-color: st-lighten(#353535, 7%); } + .switcher-list .item-box:active { + color: #ffffff; - background-color: #4c4c4c; } ++ background-color: st-lighten(#353535, 9%); } + .switcher-list .item-box:active:hover { - background-color: #5e5e5e; } ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } + .switcher-list .item-box:active:focus { - background-color: #4b4f53; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } + .switcher-list .item-box:highlighted, .switcher-list .item-box:selected, .switcher-list .item-box:checked { + color: #ffffff; - background-color: #494949; } ++ background-color: st-lighten(#353535, 8%); } + .switcher-list .item-box:highlighted:hover, .switcher-list .item-box:selected:hover, .switcher-list .item-box:checked:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 7%); } + .switcher-list .item-box:highlighted:active, .switcher-list .item-box:selected:active, .switcher-list .item-box:checked:active { - background-color: #606060; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 9%); } + .switcher-list .item-box:insensitive { - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #353535; } + .switcher-list .item-box:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .switcher-list .item-box:hover { + background: none; } + .switcher-list .item-box:selected { + background-color: rgba(255, 255, 255, 0.2); } + .switcher-list .separator { + width: 1px; + background: rgba(255, 255, 255, 0.1); } + .switcher-list .thumbnail-box { + padding: 2px; + spacing: 6px; } + .switcher-list .thumbnail { + width: 256px; + border-radius: 8px; } + +.switcher-arrow { + border-color: rgba(255, 255, 255, 0.8); + color: rgba(255, 255, 255, 0.8); } + .switcher-arrow:highlighted { + border-color: #ffffff; + color: #ffffff; } + +.input-source-switcher-symbol { + font-size: 34pt; + width: 96px; + height: 96px; } + +.cycler-highlight { - border: 5px solid #3584e4; } ++ border: 5px solid -st-accent-color; } + +/* Workspace Switcher */ +.workspace-switcher { + margin-bottom: 4em; + spacing: 12px; + padding: 12px 18px; } + +.ws-switcher-indicator { + background-color: rgba(255, 255, 255, 0.5); + padding: 2.6666666667px; + margin: 13.3333333333px; + border-radius: 32px; } + .ws-switcher-indicator:active { + background-color: #ffffff; + padding: 5.3333333333px; + margin: 10.6666666667px; } + +.screenshot-ui-panel { + border-radius: 32px; + padding: 18px; + padding-bottom: 12px; + margin-bottom: 4em; + spacing: 12px; } + +.screenshot-ui-close-button { + padding: 6px !important; + margin-top: 12px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); } + .screenshot-ui-close-button.left { + margin-left: 12px; } + .screenshot-ui-close-button.right { + margin-right: 12px; } + +.screenshot-ui-type-button { + min-width: 48px; + padding: 12px 18px; + border-radius: 14px; } + .screenshot-ui-type-button .icon-label-button-container { + spacing: 0.409em; } + .screenshot-ui-type-button .icon-label-button-container > StIcon { + icon-size: 32px; } + +.screenshot-ui-capture-button { + width: 32px; + height: 32px; + border-radius: 999px; + border: 4px #ffffff; + padding: 4px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle { + background-color: #ffffff; + transition-duration: 200ms; + border-radius: 999px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:hover, .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:focus { + background-color: #4e4e4e; } + .screenshot-ui-capture-button:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:focus .screenshot-ui-capture-button-circle { + background-color: #cccccc; } + .screenshot-ui-capture-button:active .screenshot-ui-capture-button-circle { + background-color: gray; } + .screenshot-ui-capture-button:cast .screenshot-ui-capture-button-circle { + background-color: #c01c28; } + .screenshot-ui-capture-button:cast:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:cast:focus .screenshot-ui-capture-button-circle { + background-color: #d61f2d; } + .screenshot-ui-capture-button:cast:active .screenshot-ui-capture-button-circle { + background-color: #a11722; } + +.screenshot-ui-shot-cast-container { + background-color: rgba(255, 255, 255, 0.1); + border-radius: 999px; + padding: 3px; + spacing: 3px; } + +.screenshot-ui-shot-cast-button { + padding: 6px 12px; + background-color: transparent; + border-radius: 999px; } + .screenshot-ui-shot-cast-button > StIcon { + icon-size: 16px; } + .screenshot-ui-shot-cast-button:hover, .screenshot-ui-shot-cast-button:focus { + background-color: rgba(255, 255, 255, 0.2); } + .screenshot-ui-shot-cast-button:active { + background-color: rgba(255, 255, 255, 0.5); } + .screenshot-ui-shot-cast-button:checked { + background-color: #ffffff; + color: #353535; } + .screenshot-ui-shot-cast-button:insensitive { + color: rgba(255, 255, 255, 0.5); } + +.screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.3); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.5); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-selection { + border: 2px white; } + +.screenshot-ui-area-selector-handle { + border-radius: 999px; + background-color: white; + box-shadow: 0 1px 3px 2px rgba(0, 0, 0, 0.2); + width: 24px; + height: 24px; } + +.screenshot-ui-window-selector { + background-color: #282828; } + .screenshot-ui-window-selector .screenshot-ui-window-selector-window-container { + margin: 100px; } + .screenshot-ui-window-selector:primary-monitor .screenshot-ui-window-selector-window-container { + margin-bottom: 200px; } + +.screenshot-ui-window-selector-window-border { + transition-duration: 200ms; + border-radius: 16px; + border: 6px transparent; } + +.screenshot-ui-window-selector-check { + transition-duration: 200ms; + color: transparent; + border-radius: 999px; + border-width: 12px; + icon-size: 24px; } + +.screenshot-ui-window-selector-window:hover .screenshot-ui-window-selector-window-border { - border-color: #185fb4; } ++ border-color: st-darken(-st-accent-color, 15%); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-window-border { - border-color: #3584e4; - background-color: rgba(53, 132, 228, 0.2); } ++ border-color: -st-accent-color; ++ background-color: st-transparentize(-st-accent-color, 0.8); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-check { - color: #ffffff; - background-color: #3584e4; } ++ color: -st-accent-fg-color; ++ background-color: -st-accent-color; } + +.screenshot-ui-screen-selector { + transition-duration: 200ms; + background-color: rgba(0, 0, 0, 0.5); } + .screenshot-ui-screen-selector:hover { + background-color: rgba(0, 0, 0, 0.3); } + .screenshot-ui-screen-selector:active { + background-color: rgba(0, 0, 0, 0.7); } + .screenshot-ui-screen-selector:checked { + background-color: transparent; + border: 2px white; } + +.screenshot-ui-tooltip { + text-align: center; + -y-offset: 24px; } + +/* Top Bar */ +#panel { + background-color: #000000; + font-weight: bold; + height: 2.2em; + transition-duration: 250ms; } + #panel .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 6px; } + #panel .panel-button:focus, #panel .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button:active, #panel .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button:active:hover, #panel .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button .system-status-icon { + icon-size: 1.091em; + padding: 0 6px; + margin: 0 4px; } + #panel .panel-button .app-menu-icon { + -st-icon-style: symbolic; } + #panel .panel-button .panel-status-menu-box, + #panel .panel-button .panel-status-indicators-box { + spacing: 4px; } + #panel .panel-button .panel-status-menu-box > .system-status-icon, + #panel .panel-button .panel-status-indicators-box > .system-status-icon { + padding: 0; } + #panel .panel-button#panelActivities StBoxLayout { + padding: 0 0.2045em; + spacing: 5px; } + #panel .panel-button#panelActivities .workspace-dot { + border-radius: 999px; + min-width: 0.5455em; + min-height: 0.5455em; + background-color: #ffffff; } + #panel .panel-button.screen-recording-indicator StBoxLayout, #panel .panel-button.screen-sharing-indicator StBoxLayout { + spacing: 0.409em; } + #panel .panel-button.screen-recording-indicator StIcon, #panel .panel-button.screen-sharing-indicator StIcon { + icon-size: 1.091em; } + #panel .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel .panel-button.screen-recording-indicator:focus, #panel .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #d61f2d; } + #panel .panel-button.screen-recording-indicator:active, #panel .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #e02a37; } + #panel .panel-button.screen-recording-indicator:active:hover, #panel .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #e13340; } + #panel .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #ff7800; } + #panel .panel-button.screen-sharing-indicator:focus, #panel .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #ff861a; } + #panel .panel-button.screen-sharing-indicator:active, #panel .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #ff902e; } + #panel .panel-button.screen-sharing-indicator:active:hover, #panel .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ff9638; } + #panel .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel .panel-button.clock-display:focus, #panel .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button.clock-display:active, #panel .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button.clock-display:active:hover, #panel .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button.clock-display:active .clock:hover, #panel .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button.clock-display .messages-indicator { + icon-size: 1.091em; } + #panel:overview, #panel.unlock-screen, #panel.login-screen { + background-color: transparent; } + #panel:overview .panel-button.screen-recording-indicator, #panel.unlock-screen .panel-button.screen-recording-indicator, #panel.login-screen .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel:overview .panel-button.screen-recording-indicator:focus, #panel:overview .panel-button.screen-recording-indicator:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:focus, #panel.unlock-screen .panel-button.screen-recording-indicator:hover, #panel.login-screen .panel-button.screen-recording-indicator:focus, #panel.login-screen .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #d61f2d; } + #panel:overview .panel-button.screen-recording-indicator:active, #panel:overview .panel-button.screen-recording-indicator:checked, #panel.unlock-screen .panel-button.screen-recording-indicator:active, #panel.unlock-screen .panel-button.screen-recording-indicator:checked, #panel.login-screen .panel-button.screen-recording-indicator:active, #panel.login-screen .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #e02a37; } + #panel:overview .panel-button.screen-recording-indicator:active:hover, #panel:overview .panel-button.screen-recording-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:active:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:checked:hover, #panel.login-screen .panel-button.screen-recording-indicator:active:hover, #panel.login-screen .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #e13340; } + #panel:overview .panel-button.screen-sharing-indicator, #panel.unlock-screen .panel-button.screen-sharing-indicator, #panel.login-screen .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #ff7800; } + #panel:overview .panel-button.screen-sharing-indicator:focus, #panel:overview .panel-button.screen-sharing-indicator:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:focus, #panel.unlock-screen .panel-button.screen-sharing-indicator:hover, #panel.login-screen .panel-button.screen-sharing-indicator:focus, #panel.login-screen .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #ff861a; } + #panel:overview .panel-button.screen-sharing-indicator:active, #panel:overview .panel-button.screen-sharing-indicator:checked, #panel.unlock-screen .panel-button.screen-sharing-indicator:active, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked, #panel.login-screen .panel-button.screen-sharing-indicator:active, #panel.login-screen .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #ff902e; } + #panel:overview .panel-button.screen-sharing-indicator:active:hover, #panel:overview .panel-button.screen-sharing-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:active:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked:hover, #panel.login-screen .panel-button.screen-sharing-indicator:active:hover, #panel.login-screen .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ff9638; } + #panel.unlock-screen .panel-button, #panel.login-screen .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; } + #panel.unlock-screen .panel-button:focus, #panel.unlock-screen .panel-button:hover, #panel.login-screen .panel-button:focus, #panel.login-screen .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button:active, #panel.unlock-screen .panel-button:checked, #panel.login-screen .panel-button:active, #panel.login-screen .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button:active:hover, #panel.unlock-screen .panel-button:checked:hover, #panel.login-screen .panel-button:active:hover, #panel.login-screen .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display, #panel.login-screen .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel.unlock-screen .panel-button.clock-display:focus, #panel.unlock-screen .panel-button.clock-display:hover, #panel.login-screen .panel-button.clock-display:focus, #panel.login-screen .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active, #panel.unlock-screen .panel-button.clock-display:checked, #panel.login-screen .panel-button.clock-display:active, #panel.login-screen .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active:hover, #panel.unlock-screen .panel-button.clock-display:checked:hover, #panel.login-screen .panel-button.clock-display:active:hover, #panel.login-screen .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display .clock, #panel.login-screen .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel.unlock-screen .panel-button.clock-display:focus .clock, #panel.unlock-screen .panel-button.clock-display:hover .clock, #panel.login-screen .panel-button.clock-display:focus .clock, #panel.login-screen .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active .clock, #panel.unlock-screen .panel-button.clock-display:checked .clock, #panel.login-screen .panel-button.clock-display:active .clock, #panel.login-screen .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active .clock:hover, #panel.unlock-screen .panel-button.clock-display:checked .clock:hover, #panel.login-screen .panel-button.clock-display:active .clock:hover, #panel.login-screen .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel:overview .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px transparent; } + #panel:overview .panel-button:focus, #panel:overview .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button:active, #panel:overview .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button:active:hover, #panel:overview .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel:overview .panel-button#panelActivities .workspace-dot { + background-color: whitesmoke; } + #panel:overview .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel:overview .panel-button.clock-display:focus, #panel:overview .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button.clock-display:active, #panel:overview .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button.clock-display:active:hover, #panel:overview .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel:overview .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel:overview .panel-button.clock-display:focus .clock, #panel:overview .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button.clock-display:active .clock, #panel:overview .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button.clock-display:active .clock:hover, #panel:overview .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel .panel-status-indicators-box, + #panel .panel-status-menu-box { + spacing: 2px; } + #panel .power-status.panel-status-indicators-box { + spacing: 0; } + #panel .privacy-indicator { + color: #ff7800; } + +#appMenu { + spacing: 0.409em; } + #appMenu .label-shadow { + color: transparent; } + +#appMenu .panel-status-menu-box { + padding: 0 0.409em; + spacing: 0.409em; } + +.clock-display-box { + spacing: 2px; } + .clock-display-box .clock { + padding-left: 0.818em; + padding-right: 0.818em; } + +/* Activities Ripple */ +.ripple-box { + background-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 0 2px 2px rgba(255, 255, 255, 0.2); + width: 52px; + height: 52px; + border-radius: 0 0 52px 0; } + .ripple-box:rtl { + border-radius: 0 0 0 52px; } + +.quick-settings { + padding: 18px; + border-radius: 36px; } + .quick-settings .icon-button, .quick-settings .login-dialog-button.cancel-button, .quick-settings .login-dialog-button.switch-user-button, .quick-settings .login-dialog-button.login-dialog-session-list-button, .quick-settings .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-settings .pager-button, .quick-settings .message .message-header .message-expand-button, .message .message-header .quick-settings .message-expand-button, + .quick-settings .message .message-header .message-close-button, + .message .message-header .quick-settings .message-close-button, .quick-settings .screenshot-ui-show-pointer-button, .quick-settings .button { + padding: 10.5px; } + +.quick-settings-grid { + spacing-rows: 12px; + spacing-columns: 12px; } + +.quick-toggle, .quick-menu-toggle { + border-radius: 999px; + min-width: 12em; + max-width: 12em; + min-height: 3.273em; + border: none; } + +.quick-toggle { + background-color: none; + /* Move padding into the box; this is to allow menu arrows + to extend to the border */ } + .quick-toggle > StBoxLayout { + spacing: 9px; } + .quick-toggle.button { + padding: 0; } + .quick-toggle > StBoxLayout { + padding: 0 12px; } + .quick-toggle:ltr > StBoxLayout { + padding-left: 15px; } + .quick-toggle:rtl > StBoxLayout { + padding-right: 15px; } + .quick-toggle .quick-toggle-title { + font-weight: bold; } + .quick-toggle StBoxLayout > .quick-toggle-subtitle { + font-weight: normal; } + .quick-toggle .quick-toggle-icon { + icon-size: 1.091em; } + +.quick-menu-toggle .quick-toggle { + min-width: auto; + max-width: auto; } + .quick-menu-toggle .quick-toggle:ltr { + border-radius: 999px 0 0 999px; } + .quick-menu-toggle .quick-toggle:ltr > StBoxLayout { + padding-right: 0.6135em; } + .quick-menu-toggle .quick-toggle:rtl { + border-radius: 0 999px 999px 0; } + .quick-menu-toggle .quick-toggle:rtr > StBoxLayout { + padding-left: 0.6135em; } + .quick-menu-toggle .quick-toggle:ltr:last-child { + border-radius: 999px; } + .quick-menu-toggle .quick-toggle:rtl:last-child { + border-radius: 999px; } + +.quick-menu-toggle .quick-toggle-arrow { + padding: 0.409em 0.71575em; + border-width: 0; + border-color: rgba(255, 255, 255, 0.25); } + .quick-menu-toggle .quick-toggle-arrow:checked { - border-color: #78aded; } ++ border-color: st-lighten(-st-accent-color, 15%); } + .quick-menu-toggle .quick-toggle-arrow:ltr { + border-radius: 0 999px 999px 0; + border-left-width: 1px; } + .quick-menu-toggle .quick-toggle-arrow:rtl { + border-radius: 999px 0 0 999px; + border-right-width: 1px; } + +.quick-slider > StBoxLayout { + spacing: 6px; } + +.quick-slider .icon-button, .quick-slider .login-dialog-button.cancel-button, .quick-slider .login-dialog-button.switch-user-button, .quick-slider .login-dialog-button.login-dialog-session-list-button, .quick-slider .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-slider .pager-button, .quick-slider .message .message-header .message-expand-button, .message .message-header .quick-slider .message-expand-button, +.quick-slider .message .message-header .message-close-button, +.message .message-header .quick-slider .message-close-button, .quick-slider .screenshot-ui-show-pointer-button { + padding: 6px; } + +.quick-slider .slider-bin { + padding: 6px; + border-radius: 999px; } + .quick-slider .slider-bin:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } + .quick-slider .slider-bin:focus:hover { - background-color: #505459; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } + +.quick-toggle-menu { + border-radius: 24px; + margin: 12px 18px 0; } + .quick-toggle-menu:insensitive { + color: #ffffff; - background-color: #474747; } ++ background-color: st-mix(#ffffff, #353535, 9%); } + .quick-toggle-menu .popup-menu-item > StIcon { + -st-icon-style: symbolic; + icon-size: 1.091em; } + .quick-toggle-menu .header { + spacing-rows: 3px; + spacing-columns: 12px; + padding-bottom: 12px; } + .quick-toggle-menu .header .icon { + icon-size: 1.6365em; + border-radius: 999px; + padding: 9px; + background-color: rgba(255, 255, 255, 0.2); } + .quick-toggle-menu .header .icon.active { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.quick-settings-system-item > StBoxLayout { + spacing: 12px; } + +.quick-settings-system-item .power-item { + min-height: 0; + min-width: 0; } + .quick-settings-system-item .power-item:insensitive { + color: #ffffff; - background-color: #474747; ++ background-color: st-mix(#ffffff, #353535, 9%); + background-color: transparent; } + +.nm-network-item .wireless-secure-icon { + icon-size: 0.5455em; } + +.bt-device-item .popup-menu-icon { + -st-icon-style: symbolic; } + +.bt-menu-placeholder.popup-menu-item { + text-align: center; + padding: 2em 4em; } + +.device-subtitle { + color: rgba(255, 255, 255, 0.5); } + +.keyboard-brightness-level { + spacing: 6px; } + +.background-apps-quick-toggle { + min-height: 2.728em; + background-color: transparent; } + .background-apps-quick-toggle StIcon { + icon-size: 1.091em !important; } + +.background-app-item .popup-menu-icon { + icon-size: 32px !important; + -st-icon-style: regular !important; } + +.background-app-item .icon-button, .background-app-item .login-dialog-button.cancel-button, .background-app-item .login-dialog-button.switch-user-button, .background-app-item .login-dialog-button.login-dialog-session-list-button, .background-app-item .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .background-app-item .pager-button, .background-app-item .message .message-header .message-expand-button, .message .message-header .background-app-item .message-expand-button, +.background-app-item .message .message-header .message-close-button, +.message .message-header .background-app-item .message-close-button, .background-app-item .screenshot-ui-show-pointer-button { + padding: 6px; + background-color: rgba(255, 255, 255, 0.13); } + .background-app-item .icon-button:hover, .background-app-item .login-dialog-button.cancel-button:hover, .background-app-item .login-dialog-button.switch-user-button:hover, .background-app-item .login-dialog-button.login-dialog-session-list-button:hover, .background-app-item .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .background-app-item .pager-button:hover, .background-app-item .message .message-header .message-expand-button:hover, .message .message-header .background-app-item .message-expand-button:hover, + .background-app-item .message .message-header .message-close-button:hover, + .message .message-header .background-app-item .message-close-button:hover, .background-app-item .screenshot-ui-show-pointer-button:hover { + background-color: rgba(255, 255, 255, 0.22); } + .background-app-item .icon-button:active, .background-app-item .login-dialog-button.cancel-button:active, .background-app-item .login-dialog-button.switch-user-button:active, .background-app-item .login-dialog-button.login-dialog-session-list-button:active, .background-app-item .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .background-app-item .pager-button:active, .background-app-item .message .message-header .message-expand-button:active, .message .message-header .background-app-item .message-expand-button:active, + .background-app-item .message .message-header .message-close-button:active, + .message .message-header .background-app-item .message-close-button:active, .background-app-item .screenshot-ui-show-pointer-button:active { + background-color: rgba(255, 255, 255, 0.31); } + +.background-app-item .spinner { + padding: 6px; } + +.background-app-item.popup-inactive-menu-item { + color: #ffffff; } + +/* OVERVIEW */ - .controls-manager, .secondary-monitor-workspaces { ++.secondary-monitor-workspaces { + spacing: 12px; } + +#overviewGroup { + background-color: #282828; } + - .overview-controls { - padding-bottom: 32px; } - +/* Window Picker */ +.window-picker { + spacing: 6px; } + +.window-close, .screenshot-ui-close-button { + background-color: rgba(71, 71, 71, 0.98); + color: whitesmoke; + border-radius: 999px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); + padding: 3px; + height: 32px; + width: 32px; + transition-duration: 100ms; + border: 2px solid transparent; } + .window-close StIcon, .screenshot-ui-close-button StIcon { + icon-size: 24px; } + .window-close:hover, .screenshot-ui-close-button:hover { + background-color: rgba(88, 88, 88, 0.98); } + .window-close:active, .screenshot-ui-close-button:active { + background-color: rgba(104, 104, 104, 0.98); } + +.workspace-background { + border-radius: 30px; + background-color: rgba(3, 2, 1, 0); + box-shadow: 0 4px 16px 4px rgba(0, 0, 0, 0.2); } + +.search-entry { + border-radius: 999px; + margin-top: 12px; + margin-bottom: 6px; + width: 24em; } + .search-entry .search-entry-icon { + icon-size: 1.091em; + margin-top: 2px; + padding: 0 4px; } + +/* Search */ +#searchResults { + margin: 0 4px; } + +#searchResultsContent { + max-width: 1044px; } + +.search-section { + spacing: 18px; } + .search-section .search-section-separator { + height: 8px; + background-color: transparent; } + +.search-section-content { + background-color: #3d3d3d; + color: whitesmoke; + border-radius: 24px; + padding: 12px; + margin: 0 12px; + border: 2px solid transparent; } + +.list-search-result, .search-provider-icon { + color: whitesmoke; + background-color: #3d3d3d; + border-radius: 13.2px; } + .list-search-result:focus, .search-provider-icon:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(59, 80, 106, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + .list-search-result:focus:hover, .search-provider-icon:focus:hover { - background-color: #4e5256; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + .list-search-result:hover, .search-provider-icon:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .list-search-result:active, .search-provider-icon:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .list-search-result:active:hover, .search-provider-icon:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .list-search-result:active:focus, .search-provider-icon:active:focus { - background-color: #52565b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .list-search-result:highlighted, .search-provider-icon:highlighted, .list-search-result:selected, .search-provider-icon:selected, .list-search-result:checked, .search-provider-icon:checked { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + .list-search-result:highlighted:hover, .search-provider-icon:highlighted:hover, .list-search-result:selected:hover, .search-provider-icon:selected:hover, .list-search-result:checked:hover, .search-provider-icon:checked:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + .list-search-result:highlighted:active, .search-provider-icon:highlighted:active, .list-search-result:selected:active, .search-provider-icon:selected:active, .list-search-result:checked:active, .search-provider-icon:checked:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + .list-search-result:insensitive, .search-provider-icon:insensitive { - color: rgba(245, 245, 245, 0.5); ++ color: st-transparentize(whitesmoke, 0.5); + background-color: #3d3d3d; } + .list-search-result:drop, .search-provider-icon:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.search-statustext { + color: rgba(245, 245, 245, 0.8); } + +.grid-search-results { + spacing: 30px; } + +.search-provider-icon:ltr { + margin-right: 4px; } + +.search-provider-icon:rtl { + margin-left: 4px; } + +.search-provider-icon .list-search-provider-content { + spacing: 12px; } + .search-provider-icon .list-search-provider-content .list-search-provider-details { + width: 120px; + color: whitesmoke; } + +.list-search-results { + spacing: 6px; } + +.list-search-result .list-search-result-content { + spacing: 6px; } + +.list-search-result .list-search-result-title { + spacing: 12px; } + +.list-search-result .list-search-result-description { + color: #959595; } + +/* Dash */ +#dash { - margin-top: 12px; } ++ padding-left: 6px; ++ padding-right: 6px; } + #dash .dash-background { + background-color: #3d3d3d; + border-radius: 28px; + padding-top: 12px; + padding-bottom: 12px; + padding-left: 10px; + padding-right: 10px; } + #dash .dash-item-container .placeholder { + background-image: none; + background-size: contain; + height: 32px; } + #dash .dash-item-container .empty-dash-drop-target { + width: 32px; + height: 32px; } + #dash .dash-item-container .show-apps, + #dash .dash-item-container .overview-tile, + #dash .dash-item-container .grid-search-result { + margin: 0 2px; + padding-bottom: 12px; } + #dash .dash-item-container .show-apps .overview-icon, + #dash .dash-item-container .overview-tile .overview-icon, + #dash .dash-item-container .grid-search-result .overview-icon { + color: whitesmoke; + background-color: #3d3d3d; } + #dash .dash-item-container .show-apps:focus .overview-icon, + #dash .dash-item-container .overview-tile:focus .overview-icon, + #dash .dash-item-container .grid-search-result:focus .overview-icon { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(59, 80, 106, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + #dash .dash-item-container .show-apps:focus .overview-icon:hover, + #dash .dash-item-container .overview-tile:focus .overview-icon:hover, + #dash .dash-item-container .grid-search-result:focus .overview-icon:hover { - background-color: #4e5256; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + #dash .dash-item-container .show-apps:hover .overview-icon, + #dash .dash-item-container .overview-tile:hover .overview-icon, + #dash .dash-item-container .grid-search-result:hover .overview-icon { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + #dash .dash-item-container .show-apps:active .overview-icon, + #dash .dash-item-container .overview-tile:active .overview-icon, + #dash .dash-item-container .grid-search-result:active .overview-icon { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + #dash .dash-item-container .show-apps:active .overview-icon:hover, + #dash .dash-item-container .overview-tile:active .overview-icon:hover, + #dash .dash-item-container .grid-search-result:active .overview-icon:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + #dash .dash-item-container .show-apps:active .overview-icon:focus, + #dash .dash-item-container .overview-tile:active .overview-icon:focus, + #dash .dash-item-container .grid-search-result:active .overview-icon:focus { - background-color: #52565b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + #dash .dash-item-container .show-apps:checked .overview-icon, + #dash .dash-item-container .overview-tile:checked .overview-icon, + #dash .dash-item-container .grid-search-result:checked .overview-icon { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + #dash .dash-item-container .show-apps:checked .overview-icon:hover, + #dash .dash-item-container .overview-tile:checked .overview-icon:hover, + #dash .dash-item-container .grid-search-result:checked .overview-icon:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + #dash .dash-item-container .show-apps:checked .overview-icon:active, + #dash .dash-item-container .overview-tile:checked .overview-icon:active, + #dash .dash-item-container .grid-search-result:checked .overview-icon:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + #dash .dash-item-container .app-grid-running-dot { + offset-y: -12px; } + #dash .dash-separator { + width: 1px; + margin-left: 4px; + margin-right: 4px; + background-color: rgba(245, 245, 245, 0.1); } + #dash .dash-separator, + #dash .dash-background { + margin-bottom: 12px; } + +.dash-label { + -y-offset: 8px; } + +/* App Grid */ +.icon-grid { + row-spacing: 12px; + column-spacing: 12px; + max-row-spacing: 36px; + max-column-spacing: 36px; + page-padding-top: 24px; + page-padding-bottom: 24px; + page-padding-left: 18px; + page-padding-right: 18px; } + +/* App Icons */ +.overview-tile, .grid-search-result { + color: whitesmoke; + background-color: #282828; + border-radius: 24px; + padding: 12px; } + .overview-tile:focus, .grid-search-result:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(44, 65, 91, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.25), 5%); } + .overview-tile:focus:hover, .grid-search-result:focus:hover { - background-color: #3a3e42; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 7%), 5%); } + .overview-tile:hover, .grid-search-result:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .overview-tile:active, .grid-search-result:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .overview-tile:active:hover, .grid-search-result:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .overview-tile:active:focus, .grid-search-result:active:focus { - background-color: #3e4247; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + .overview-tile:highlighted, .grid-search-result:highlighted, .overview-tile:selected, .grid-search-result:selected, .overview-tile:checked, .grid-search-result:checked { + color: whitesmoke; - background-color: #3c3c3c; } ++ background-color: st-lighten(#282828, 8%); } + .overview-tile:highlighted:hover, .grid-search-result:highlighted:hover, .overview-tile:selected:hover, .grid-search-result:selected:hover, .overview-tile:checked:hover, .grid-search-result:checked:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#282828, 8%), 7%); } + .overview-tile:highlighted:active, .grid-search-result:highlighted:active, .overview-tile:selected:active, .grid-search-result:selected:active, .overview-tile:checked:active, .grid-search-result:checked:active { - background-color: #535353; } ++ background-color: st-lighten(st-lighten(#282828, 8%), 9%); } + .overview-tile:insensitive, .grid-search-result:insensitive { - color: rgba(245, 245, 245, 0.5); ++ color: st-transparentize(whitesmoke, 0.5); + background-color: #282828; } + .overview-tile:drop, .grid-search-result:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .overview-tile .overview-icon.overview-icon-with-label > StBoxLayout, .grid-search-result .overview-icon.overview-icon-with-label > StBoxLayout { + spacing: 6px; } + +.app-folder { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-mix(whitesmoke, #282828, 9%); } + .app-folder:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #3a3e43; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #282828, 9%), 5%); } + .app-folder:focus:hover { - background-color: #43474c; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 9%), 4%), 5%); } + .app-folder:hover { + color: whitesmoke; - background-color: #444444; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 9%), 4%); } + .app-folder:active { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 9%), 9%); } + .app-folder:active:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 9%), 9%), 4%); } + .app-folder:active:focus { - background-color: #505458; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 9%), 9%), 5%); } + .app-folder:highlighted, .app-folder:selected, .app-folder:checked { + color: whitesmoke; - background-color: #4e4e4e; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 9%), 8%); } + .app-folder:highlighted:hover, .app-folder:selected:hover, .app-folder:checked:hover { - background-color: #595959; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 9%), 8%), 4%); } + .app-folder:highlighted:active, .app-folder:selected:active, .app-folder:checked:active { - background-color: #656565; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 9%), 8%), 9%); } + .app-folder:insensitive { - color: rgba(245, 245, 245, 0.5); - background-color: #323232; } ++ color: st-transparentize(whitesmoke, 0.5); ++ background-color: st-darken(st-mix(whitesmoke, #282828, 9%), 3%); } + .app-folder:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.app-grid-running-dot { + height: 5px; + width: 5px; + border-radius: 5px; + background-color: whitesmoke; + offset-y: 6px; } + +.app-folder-dialog-container { + padding-top: 2.2em; } + +.app-folder-dialog { + width: 720px; + height: 720px; + border-radius: 64px; + background-color: #3d3d3d; + color: whitesmoke; + padding: 0 1px; + box-shadow: inset 0 0 0 1px rgba(245, 245, 245, 0.1); } + .app-folder-dialog .folder-name-container { + padding: 24px 36px; + padding-bottom: 0; } + .app-folder-dialog .folder-name-container .folder-name-entry { + width: 12em; } + .app-folder-dialog .icon-button, .app-folder-dialog .login-dialog-button.cancel-button, .app-folder-dialog .login-dialog-button.switch-user-button, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button, .app-folder-dialog .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .app-folder-dialog .pager-button, .app-folder-dialog .message .message-header .message-expand-button, .message .message-header .app-folder-dialog .message-expand-button, + .app-folder-dialog .message .message-header .message-close-button, + .message .message-header .app-folder-dialog .message-close-button, .app-folder-dialog .screenshot-ui-show-pointer-button { + color: whitesmoke; - background-color: #4e4e4e; } ++ background-color: st-mix(whitesmoke, #3d3d3d, 9%); } + .app-folder-dialog .icon-button:hover, .app-folder-dialog .login-dialog-button.cancel-button:hover, .app-folder-dialog .login-dialog-button.switch-user-button:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:hover, .app-folder-dialog .message .message-header .message-expand-button:hover, .message .message-header .app-folder-dialog .message-expand-button:hover, + .app-folder-dialog .message .message-header .message-close-button:hover, + .message .message-header .app-folder-dialog .message-close-button:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:hover { + color: whitesmoke; - background-color: #585858; } ++ background-color: st-lighten(st-mix(whitesmoke, #3d3d3d, 9%), 4%); } + .app-folder-dialog .icon-button:active, .app-folder-dialog .login-dialog-button.cancel-button:active, .app-folder-dialog .login-dialog-button.switch-user-button:active, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active, .app-folder-dialog .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .app-folder-dialog .pager-button:active, .app-folder-dialog .message .message-header .message-expand-button:active, .message .message-header .app-folder-dialog .message-expand-button:active, + .app-folder-dialog .message .message-header .message-close-button:active, + .message .message-header .app-folder-dialog .message-close-button:active, .app-folder-dialog .screenshot-ui-show-pointer-button:active { + color: whitesmoke; - background-color: #656565; } ++ background-color: st-lighten(st-mix(whitesmoke, #3d3d3d, 9%), 9%); } + .app-folder-dialog .icon-button:active:hover, .app-folder-dialog .login-dialog-button.cancel-button:active:hover, .app-folder-dialog .login-dialog-button.switch-user-button:active:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:hover, .app-folder-dialog .message .message-header .message-expand-button:active:hover, .message .message-header .app-folder-dialog .message-expand-button:active:hover, + .app-folder-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .app-folder-dialog .message-close-button:active:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:active:hover { - background-color: #6f6f6f; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #3d3d3d, 9%), 9%), 4%); } + .app-folder-dialog .icon-button:active:focus, .app-folder-dialog .login-dialog-button.cancel-button:active:focus, .app-folder-dialog .login-dialog-button.switch-user-button:active:focus, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:focus, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:focus, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:focus, .app-folder-dialog .message .message-header .message-expand-button:active:focus, .message .message-header .app-folder-dialog .message-expand-button:active:focus, + .app-folder-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .app-folder-dialog .message-close-button:active:focus, .app-folder-dialog .screenshot-ui-show-pointer-button:active:focus { - background-color: #63676b; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #3d3d3d, 9%), 9%), 5%); } + .app-folder-dialog .page-indicators { + margin-bottom: 24px; } + .app-folder-dialog .page-navigation-arrow { + color: whitesmoke; + background-color: #3d3d3d; } + .app-folder-dialog .page-navigation-arrow:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .app-folder-dialog .page-navigation-arrow:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .app-folder-dialog .page-navigation-arrow:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .app-folder-dialog .page-navigation-arrow:active:focus { - background-color: #52565b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result { + color: whitesmoke; + background-color: #3d3d3d; } + .app-folder-dialog .overview-tile:focus, .app-folder-dialog .grid-search-result:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(59, 80, 106, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + .app-folder-dialog .overview-tile:focus:hover, .app-folder-dialog .grid-search-result:focus:hover { - background-color: #4e5256; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + .app-folder-dialog .overview-tile:hover, .app-folder-dialog .grid-search-result:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .app-folder-dialog .overview-tile:active, .app-folder-dialog .grid-search-result:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .app-folder-dialog .overview-tile:active:hover, .app-folder-dialog .grid-search-result:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .app-folder-dialog .overview-tile:active:focus, .app-folder-dialog .grid-search-result:active:focus { - background-color: #52565b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .app-folder-dialog .overview-tile:highlighted, .app-folder-dialog .grid-search-result:highlighted, .app-folder-dialog .overview-tile:selected, .app-folder-dialog .grid-search-result:selected, .app-folder-dialog .overview-tile:checked, .app-folder-dialog .grid-search-result:checked { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + .app-folder-dialog .overview-tile:highlighted:hover, .app-folder-dialog .grid-search-result:highlighted:hover, .app-folder-dialog .overview-tile:selected:hover, .app-folder-dialog .grid-search-result:selected:hover, .app-folder-dialog .overview-tile:checked:hover, .app-folder-dialog .grid-search-result:checked:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + .app-folder-dialog .overview-tile:highlighted:active, .app-folder-dialog .grid-search-result:highlighted:active, .app-folder-dialog .overview-tile:selected:active, .app-folder-dialog .grid-search-result:selected:active, .app-folder-dialog .overview-tile:checked:active, .app-folder-dialog .grid-search-result:checked:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + .app-folder-dialog .overview-tile:insensitive, .app-folder-dialog .grid-search-result:insensitive { - color: rgba(245, 245, 245, 0.5); ++ color: st-transparentize(whitesmoke, 0.5); + background-color: #3d3d3d; } + .app-folder-dialog .overview-tile:drop, .app-folder-dialog .grid-search-result:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.rename-folder-popup .rename-folder-popup-item { + spacing: 6px; } + .rename-folder-popup .rename-folder-popup-item:ltr, .rename-folder-popup .rename-folder-popup-item:rtl { + padding: 0 12px; } + +.page-indicator { + padding: 6px 12px 0; + transition-duration: 400ms; } + .page-indicator .page-indicator-icon { + width: 10px; + height: 10px; + border-radius: 999px; + background-color: whitesmoke; + transition-duration: 400ms; } + +.apps-scroll-view { + padding: 0; } + +.system-action-icon { + background-color: rgba(245, 245, 245, 0.1); + color: whitesmoke; + border-radius: 999px; + icon-size: 48px; } + +.page-navigation-hint.dnd { + background: rgba(255, 255, 255, 0.1); } + +.page-navigation-hint.next:ltr, .page-navigation-hint.previous:rtl { + background-gradient-start: rgba(255, 255, 255, 0.05); + background-gradient-end: transparent; + background-gradient-direction: horizontal; + border-radius: 24px 0px 0px 24px; } + +.page-navigation-hint.previous:ltr, .page-navigation-hint.next:rtl { + background-gradient-start: transparent; + background-gradient-end: rgba(255, 255, 255, 0.05); + background-gradient-direction: horizontal; + border-radius: 0px 24px 24px 0px; } + +.page-navigation-arrow { + margin: 6px; + padding: 18px; + width: 24px; + height: 24px; + border-radius: 999px; + transition-duration: 100ms; + color: whitesmoke; + background-color: #282828; } + .page-navigation-arrow > StIcon { + color: whitesmoke; } + .page-navigation-arrow:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .page-navigation-arrow:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .page-navigation-arrow:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .page-navigation-arrow:active:focus { - background-color: #3e4247; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + +/* Workspace pager */ +.workspace-thumbnails { + visible-width: 32px; + spacing: 6px; + padding: 6px; } + .workspace-thumbnails .workspace-thumbnail { + color: whitesmoke; + background-color: #4e4e4e; + border-radius: 4px; + border: 1px solid transparent; } + .workspace-thumbnails .placeholder { + background-image: url("resource:///org/gnome/shell/theme/workspace-placeholder.svg"); + background-size: contain; + width: 18px; } + +.workspace-thumbnail-indicator { - border: 3px solid #3584e4; ++ border: 3px solid -st-accent-color; + border-radius: 8px; } + +.ripple-pointer-location { + width: 50px; + height: 50px; + border-radius: 25px; - background-color: rgba(188, 214, 246, 0.3); - box-shadow: 0 0 2px 2px #8fbbf0; } ++ background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 30%); ++ box-shadow: 0 0 2px 2px st-lighten(-st-accent-color, 20%); } + +.pie-timer { + width: 60px; + height: 60px; + -pie-border-width: 3px; - -pie-border-color: #3584e4; - -pie-background-color: rgba(233, 242, 252, 0.3); } ++ -pie-border-color: -st-accent-color; ++ -pie-background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 40%); } + +.magnifier-zoom-region { - border: 2px solid #3584e4; } ++ border: 2px solid -st-accent-color; } + .magnifier-zoom-region.full-screen { + border-width: 0; } + +.select-area-rubberband { - background-color: rgba(53, 132, 228, 0.3); - border: 1px solid #3584e4; } ++ background-color: st-transparentize(-st-accent-color, 0.7); ++ border: 1px solid -st-accent-color; } + +.user-icon { + background-size: contain; + border-radius: 999px; + icon-size: 64px; + background-color: rgba(255, 255, 255, 0.05); + color: #ffffff; } + .user-icon StIcon { + padding: 12px; } + .user-icon.user-avatar { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); } + +.lightbox { + background-color: black; } + +.flashspot { + background-color: white; } + +.hidden { + color: transparent; } + +.caps-lock-warning-label { + text-align: center; + padding-bottom: 8px; + color: #f6d32d; } + +/* Workspace animation */ +.workspace-animation { + background-color: #353535; } + +/* Tiled window previews */ +.tile-preview { - background-color: rgba(53, 132, 228, 0.5); - border: 1px solid #3584e4; } ++ background-color: st-transparentize(-st-accent-color, 0.5); ++ border: 1px solid -st-accent-color; } + +/* On-screen Keyboard */ +#keyboard { + background-color: #353535; + box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.02); } + #keyboard .page-indicator { + padding: 6px; } + #keyboard .page-indicator .page-indicator-icon { + width: 8px; + height: 8px; } + +.key-container { + padding: 4px; + spacing: 4px; } + +.keyboard-key { + font-size: 1.455em; + font-weight: bold; + min-height: 1.2em; + min-width: 1.2em; + border-width: 1px; + border-style: solid; + border-radius: 10px; + box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2); + color: #ffffff; - background-color: #5d5d5d; } ++ background-color: st-mix(#ffffff, #4d4d4d, 9%); } + .keyboard-key:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } + .keyboard-key:focus:hover { - background-color: #505459; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } + .keyboard-key:hover { + color: #ffffff; - background-color: #676767; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%); } + .keyboard-key:active { + color: #ffffff; - background-color: #747474; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%); } + .keyboard-key:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .keyboard-key:active:focus { - background-color: #71757a; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 5%); } + .keyboard-key:checked { + color: #ffffff; - background-color: #717171; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%); } + .keyboard-key:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .keyboard-key:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + .keyboard-key:grayed { + background-color: #2d2d2d; + color: #ffffff; + border-color: rgba(255, 255, 255, 0.1); } + .keyboard-key.default-key { + color: #ffffff; - background-color: #454545; ++ background-color: st-mix(#ffffff, #333333, 9%); + border-radius: 10px; } + .keyboard-key.default-key:hover { + color: #ffffff; - background-color: #4f4f4f; } ++ background-color: st-lighten(st-mix(#ffffff, #333333, 9%), 4%); } + .keyboard-key.default-key:active { + color: #ffffff; - background-color: #5c5c5c; } ++ background-color: st-lighten(st-mix(#ffffff, #333333, 9%), 9%); } + .keyboard-key.default-key:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 9%), 4%); } + .keyboard-key.default-key:active:focus { - background-color: #5a5e63; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #333333, 9%), 9%), 5%); } + .keyboard-key.default-key:checked { + color: #ffffff; - background-color: #595959; } ++ background-color: st-lighten(st-mix(#ffffff, #333333, 9%), 8%); } + .keyboard-key.default-key:checked:hover { - background-color: #646464; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 8%), 4%); } + .keyboard-key.default-key:checked:active { - background-color: #707070; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 8%), 9%); } + .keyboard-key.default-key:latched { - border-color: #4b92e7; - background-color: #3584e4; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + .keyboard-key.enter-key { - color: #ffffff; - background-color: #478fe6; ++ color: -st-accent-fg-color; ++ background-color: st-mix(-st-accent-fg-color, -st-accent-color, 9%); + border-radius: 10px; + color: #ffffff; } + .keyboard-key.enter-key:hover { - color: #ffffff; - background-color: #599ae8; } ++ color: -st-accent-fg-color; ++ background-color: st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 4%); } + .keyboard-key.enter-key:active { - color: #ffffff; - background-color: #6fa8eb; } ++ color: -st-accent-fg-color; ++ background-color: st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%); } + .keyboard-key.enter-key:active:hover { - background-color: #81b3ee; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%), 4%); } + .keyboard-key.enter-key:active:focus { - background-color: #6ca6eb; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%), 5%); } + .keyboard-key.enter-key:checked { - color: #ffffff; - background-color: #6ba5eb; } ++ color: -st-accent-fg-color; ++ background-color: st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%); } + .keyboard-key.enter-key:checked:hover { - background-color: #7db0ed; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%), 4%); } + .keyboard-key.enter-key:checked:active { - background-color: #93bdf0; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%), 9%); } + .keyboard-key.shift-key-uppercase { + background-color: gray; + color: #353535; } + .keyboard-key.shift-key-uppercase:hover { + background-color: #8c8c8c; + color: #424242; } + .keyboard-key StIcon { + icon-size: 24px; } + +.keyboard-subkeys { + -arrow-border-radius: 16px; + -arrow-background-color: #353535; + -arrow-border-width: 1px; + -arrow-border-color: #4c4c4c; + -arrow-base: 20px; + -arrow-rise: 10px; + -boxpointer-gap: 6px; + padding: 6px; } + .keyboard-subkeys .keyboard-key { + color: #ffffff; - background-color: #5d5d5d; ++ background-color: st-mix(#ffffff, #4d4d4d, 9%); + border-radius: 10px; } + .keyboard-subkeys .keyboard-key:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } + .keyboard-subkeys .keyboard-key:focus:hover { - background-color: #505459; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } + .keyboard-subkeys .keyboard-key:hover { + color: #ffffff; - background-color: #676767; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%); } + .keyboard-subkeys .keyboard-key:active { + color: #ffffff; - background-color: #747474; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%); } + .keyboard-subkeys .keyboard-key:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .keyboard-subkeys .keyboard-key:active:focus { - background-color: #71757a; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 5%); } + .keyboard-subkeys .keyboard-key:checked { + color: #ffffff; - background-color: #717171; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%); } + .keyboard-subkeys .keyboard-key:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .keyboard-subkeys .keyboard-key:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + +.emoji-page .keyboard-key { + background-color: transparent; + border: none; + color: initial; } + +.emoji-panel .keyboard-key:latched { - border-color: #4b92e7; - background-color: #3584e4; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + +.word-suggestions { + spacing: 12px; + min-height: 17pt; + padding: 12px; + color: #ffffff; } + .word-suggestions StButton { + margin: 0 3px; + min-width: 32px; + border-radius: 4px; + padding: 0px 18px; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .word-suggestions StButton:insensitive { + background-color: transparent !important; } + .word-suggestions StButton:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #464a4f; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 9%), 5%); } + .word-suggestions StButton:focus:hover { - background-color: #505459; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 4%), 5%); } + .word-suggestions StButton:hover { + color: #ffffff; - background-color: #676767; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%); } + .word-suggestions StButton:active { + color: #ffffff; - background-color: #747474; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%); } + .word-suggestions StButton:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .word-suggestions StButton:active:focus { - background-color: #71757a; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 5%); } + .word-suggestions StButton:checked { + color: #ffffff; - background-color: #717171; } ++ background-color: st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%); } + .word-suggestions StButton:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .word-suggestions StButton:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + +/* Looking Glass */ ++.lg-dialog StEntry { ++ min-height: 1.5em; } ++ ++.lg-dialog .shell-link { ++ color: st-lighten(-st-accent-color, 20%); } ++ .lg-dialog .shell-link:hover { ++ color: st-lighten(st-lighten(-st-accent-color, 20%), 10%); } ++ .lg-dialog .shell-link:active { ++ color: st-darken(st-lighten(-st-accent-color, 20%), 10%); } ++ ++.lg-dialog .actor-link { ++ color: st-darken(#ffffff, 20%); } ++ .lg-dialog .actor-link:hover { ++ color: #ffffff; } ++ .lg-dialog .actor-link:active { ++ color: st-lighten(#ffffff, 20%); } ++ .lg-dialog .actor-link StIcon { ++ icon-size: 12px; } ++ ++.lg-completions-text { ++ font-style: italic; } ++ +#LookingGlassDialog { + background-color: rgba(53, 53, 53, 0.98); + color: #ffffff; + border-radius: 16px; + margin-top: 4px; + border: 2px solid transparent; + padding: 6px; + spacing: 6px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); } + #LookingGlassDialog > #Toolbar { + border: none; + padding: 6px; + border-radius: 0; + background-color: transparent; + spacing: 6px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button { + padding: 6px 12px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button > StIcon { + icon-size: 16px; } + #LookingGlassDialog .labels { + spacing: 6px; } + #LookingGlassDialog .notebook-tab { ++ background-color: transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 12px; + padding: 6px 12px; } - #LookingGlassDialog StBoxLayout#EvalBox { - padding: 4px; - spacing: 6px; - padding: 6px; } - #LookingGlassDialog StBoxLayout#ResultsArea { - spacing: 6px; - padding: 6px; } - - .lg-dialog StEntry { - min-height: 1.5em; } - - .lg-dialog .shell-link { - color: #62a0ea; } - .lg-dialog .shell-link:hover { - color: #8fbbf0; } - .lg-dialog .shell-link:active { - color: #3585e4; } - - .lg-dialog .actor-link { - color: #9a9a9a; } - .lg-dialog .actor-link:hover { - color: #cdcdcd; } - .lg-dialog .actor-link:active { - color: #676767; } - .lg-dialog .actor-link StIcon { - icon-size: 12px; } - - .lg-completions-text { - font-style: italic; } - - .lg-obj-inspector-title { - spacing: 6px; } ++ #LookingGlassDialog .notebook-tab:selected { ++ color: #ffffff; ++ background-color: st-lighten(st-mix(#ffffff, #353535, 9%), 9%); } ++ #LookingGlassDialog .notebook-tab:selected:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 4%); } ++ #LookingGlassDialog .notebook-tab:selected:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 9%), 9%), 5%); } + - .lg-obj-inspector-button { ++#LookingGlassPropertyInspector { ++ background-color: #353535; ++ color: #ffffff; ++ border-radius: 16px; + border: 1px solid rgba(255, 255, 255, 0.1); - padding: 4px; - border-radius: 8px; } - .lg-obj-inspector-button:hover { - border: 1px solid #ffffff; } ++ padding: 12px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-title { ++ spacing: 4px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button { ++ padding: 6px 12px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button { ++ margin: 4px; ++ padding: 6px; ++ border-radius: 999px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button > StIcon { ++ icon-size: 16px; } + - #lookingGlassExtensions { ++#LookingGlassEvaluator { + padding: 6px; } ++ #LookingGlassEvaluator .evaluator-results { ++ spacing: 6px; } + - .lg-extensions-list { ++#LookingGlassWindows { + padding: 6px; + spacing: 6px; } ++ #LookingGlassWindows .lg-window { ++ color: #ffffff; ++ background-color: st-mix(#ffffff, #353535, 9%); ++ margin: 0; ++ padding: 12px; } + - .lg-extension-meta { ++#LookingGlassExtensions .lg-extensions-list { ++ padding: 6px; + spacing: 6px; } + - #LookingGlassPropertyInspector { - background: #353535; - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 8px; - padding: 6px; } ++#LookingGlassExtensions .lg-extension { ++ color: #ffffff; ++ background-color: st-mix(#ffffff, #353535, 9%); ++ margin: 0; ++ spacing: 4px; ++ padding: 12px; } ++ #LookingGlassExtensions .lg-extension .lg-extension-name { ++ color: #ffffff !important; } ++ #LookingGlassExtensions .lg-extension .lg-extension-meta { ++ spacing: 12px; } + - .lg-debug-flag-button { - color: #ffffff; } - .lg-debug-flag-button StLabel { - padding: 6px, 12px; } - .lg-debug-flag-button:hover { - color: white; } - .lg-debug-flag-button:active { - color: #cccccc; } ++#LookingGlassExtensions .lg-extensions-none { ++ color: rgba(255, 255, 255, 0.5); } + - .lg-debug-flags-header { - padding-top: 12px; - padding: 6px; } ++#LookingGlassActors { ++ padding: 6px; ++ spacing: 4px; } ++ ++#LookingGlassDebugFlags .lg-debug-flags-header { ++ padding: 6px; ++ padding-top: 12px; } ++ ++#LookingGlassDebugFlags .lg-debug-flag-button { ++ padding: 9px 12px; ++ margin-bottom: 6px; } ++ #LookingGlassDebugFlags .lg-debug-flag-button StLabel { ++ font-weight: normal !important; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch { ++ background: rgba(255, 255, 255, 0.15); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:hover { ++ background: rgba(255, 255, 255, 0.2); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } + +.login-dialog, +.unlock-dialog { + color: whitesmoke; } + .login-dialog .caps-lock-warning-label, + .login-dialog .login-dialog-message-warning, + .unlock-dialog .caps-lock-warning-label, + .unlock-dialog .login-dialog-message-warning { + color: whitesmoke; } + .login-dialog .login-dialog-prompt-layout, + .unlock-dialog .login-dialog-prompt-layout { + width: 25em; + spacing: 9px; } + +.login-dialog-button.cancel-button { + padding: 9px; } + +.login-dialog-button-box { + spacing: 12px; } + +.conflicting-session-dialog-content { + spacing: 20px; } + .conflicting-session-dialog-content .conflicting-session-dialog-title { + text-align: center; + margin-bottom: 5px; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc { + text-align: center; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc-warning { + text-align: center; + color: #f6d32d; } + +.login-dialog-logo-bin { + margin: 3em 0; } + +.login-dialog-banner-view { + max-width: 25em; } + .login-dialog-banner-view .login-dialog-banner { + color: gainsboro; } + +.login-dialog-message { + text-align: center; } + +.login-dialog-message-hint, .login-dialog-message { + color: gainsboro; + min-height: 2.75em; } + +.login-dialog-user-selection-box { + padding-top: 4em; + padding-bottom: 8em; } + +.login-dialog-not-listed-label { + padding: 6px; } + +.login-dialog-not-listed-button { + color: whitesmoke; + background-color: #282828; + padding: 0 6px; + margin: 6px; } + .login-dialog-not-listed-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: rgba(44, 65, 91, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.25), 5%); } + .login-dialog-not-listed-button:focus:hover { - background-color: #3a3e42; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 7%), 5%); } + .login-dialog-not-listed-button:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .login-dialog-not-listed-button:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .login-dialog-not-listed-button:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .login-dialog-not-listed-button:active:focus { - background-color: #3e4247; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + +.login-dialog-auth-list-view { + -st-vfade-offset: 3em; } + +.login-dialog-auth-list { + spacing: 6px; + margin-left: 2em; } + +.login-dialog-auth-list-title { + margin-left: 2em; } + +.login-dialog-auth-list-item { + border-radius: 16px; + padding: 4px; + color: darkgray; } + .login-dialog-auth-list-item:focus, .login-dialog-auth-list-item:selected { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.login-dialog-auth-list-label:ltr { + padding-left: 15px; + text-align: left; } + +.login-dialog-auth-list-label:rtl { + padding-right: 15px; + text-align: right; } + +.login-dialog-user-list-view { + width: 25em; + -st-vfade-offset: 3em; } + .login-dialog-user-list-view .login-dialog-user-list { + margin: 0 8px; + spacing: 12px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item { + color: whitesmoke; - background-color: #3a3a3a; ++ background-color: st-mix(whitesmoke, #282828, 9%); + border-radius: 16px; + padding: 9px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.5) !important; - background-color: #3a3e43; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #282828, 9%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected:hover, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus:hover { - background-color: #43474c; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 9%), 4%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:hover { + color: whitesmoke; - background-color: #444444; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 9%), 4%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 9%), 9%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 9%), 9%), 4%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:focus { - background-color: #505458; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 9%), 9%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .user-icon { + border: 2px solid transparent; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: rgba(245, 245, 245, 0.7); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon { - border-color: #3584e4; } ++ border-color: -st-accent-color; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon StIcon { - background-color: rgba(53, 132, 228, 0.3); } ++ background-color: st-transparentize(-st-accent-color, 0.7); } + +.unlock-dialog { + background-color: transparent; } + +.screen-shield-background { + background: black; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); } + +#lockDialogGroup { + background-color: #282828; } + +.unlock-dialog-clock { + color: whitesmoke; + spacing: 2em; } + .unlock-dialog-clock .unlock-dialog-clock-time { + font-size: 6.546em; - font-weight: 200; } ++ font-weight: 800; } + .unlock-dialog-clock .unlock-dialog-clock-date { + font-weight: 400; } + .unlock-dialog-clock .unlock-dialog-clock-hint { + margin-top: 2em; + padding: 6px 18px; + border-radius: 16px; + font-weight: bold; } + +#unlockDialogNotifications StButton#vhandle, #unlockDialogNotifications StButton#hhandle { + background-color: rgba(53, 53, 53, 0.3); } + #unlockDialogNotifications StButton#vhandle:hover, #unlockDialogNotifications StButton#vhandle:focus, #unlockDialogNotifications StButton#hhandle:hover, #unlockDialogNotifications StButton#hhandle:focus { + background-color: rgba(53, 53, 53, 0.5); } + #unlockDialogNotifications StButton#vhandle:active, #unlockDialogNotifications StButton#hhandle:active { - background-color: rgba(53, 132, 228, 0.5); } ++ background-color: st-transparentize(-st-accent-color, 0.5); } + +.unlock-dialog-notifications-container { + margin: 12px; + spacing: 6px; + width: 25em; + background-color: transparent; } + .unlock-dialog-notifications-container .summary-notification-stack-scrollview { + padding-top: 0; + padding-bottom: 0; } + .unlock-dialog-notifications-container .notification, + .unlock-dialog-notifications-container .unlock-dialog-notification-source { + padding: 12px 16px; + border: none; + background-color: rgba(245, 245, 245, 0.1); + color: whitesmoke; + border-radius: 16px; } + .unlock-dialog-notifications-container .notification.critical, + .unlock-dialog-notifications-container .unlock-dialog-notification-source.critical { + background-color: rgba(245, 245, 245, 0.2); } + +.unlock-dialog-notification-icon { + icon-size: 32px; } + +.unlock-dialog-notification-label { + padding-left: 12px; + padding-right: 0; } + .unlock-dialog-notification-label:rtl { + padding-right: 12px; + padding-left: 0; } + +.unlock-dialog-notification-count-text { + font-weight: bold; + padding: 0 12px; + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.1); + border-radius: 999px; } + +.login-dialog .user-widget .user-widget-label, +.unlock-dialog .user-widget .user-widget-label { + color: whitesmoke; } + +.login-dialog .user-widget .user-icon, +.unlock-dialog .user-widget .user-icon { + background-color: rgba(245, 245, 245, 0.13); + color: whitesmoke; } + +.login-dialog .user-widget.horizontal, +.unlock-dialog .user-widget.horizontal { + spacing: 18px; } + +.login-dialog .user-widget.vertical, +.unlock-dialog .user-widget.vertical { + spacing: 24px; } + .login-dialog .user-widget.vertical .user-widget-label, + .unlock-dialog .user-widget.vertical .user-widget-label { ++ font-weight: 400; ++ font-size: 1.818em; + text-align: center; + margin-bottom: .75em; } + .login-dialog .user-widget.vertical .user-icon, + .unlock-dialog .user-widget.vertical .user-icon { + icon-size: 160px; } + .login-dialog .user-widget.vertical .user-icon StIcon, + .unlock-dialog .user-widget.vertical .user-icon StIcon { - padding: 24px; } ++ padding: 30px; } diff --cc data/theme/gnome-shell-high-contrast.css index beb4da94a,000000000..53bf66a3c mode 100644,000000..100644 --- a/data/theme/gnome-shell-high-contrast.css +++ b/data/theme/gnome-shell-high-contrast.css @@@ -1,3419 -1,0 +1,3541 @@@ +/* This stylesheet is generated, DO NOT EDIT */ +/* Copyright 2009, 2015 Red Hat, Inc. + * + * Portions adapted from Mx's data/style/default.css + * Copyright 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* Global Values */ +stage { + font-size: 1em; + color: #ffffff; } + +/* Common Stylings */ +#dash .dash-item-container .show-apps, +#dash .dash-item-container .overview-tile, +#dash .dash-item-container .grid-search-result { + background: none; + box-shadow: none; + border: none; + border-radius: 0; + padding: 0; + margin: 0; } + +.app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result, .app-folder, .overview-tile, .grid-search-result, #dash .dash-item-container .show-apps .overview-icon, +#dash .dash-item-container .overview-tile .overview-icon, +#dash .dash-item-container .grid-search-result .overview-icon, .list-search-result, .search-provider-icon, .switcher-list .item-box { + border-radius: 16px; + padding: 6px; + spacing: 6px; + text-align: center; + transition-duration: 100ms; } + +.login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item, .login-dialog-not-listed-button, .unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, - .unlock-dialog .screenshot-ui-show-pointer-button, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, ++.unlock-dialog .screenshot-ui-show-pointer-button, #LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + border-radius: 8px; + padding: 3px 24px; + font-weight: bold; + transition: border-width 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } ++ background-color: st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%); } + .icon-button:focus, .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus, .screenshot-ui-show-pointer-button:focus, .message .message-header .message-expand-button:focus, + .message .message-header .message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #484c51; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%), 5%); } + .icon-button:focus:hover, .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .message .message-header .message-expand-button:focus:hover, + .message .message-header .message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button:focus:hover { - background-color: #515559; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%), 5%); } + .icon-button:hover, .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover, .screenshot-ui-show-pointer-button:hover, .message .message-header .message-expand-button:hover, + .message .message-header .message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #525252; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%); } + .icon-button:insensitive, .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive, .screenshot-ui-show-pointer-button:insensitive, .message .message-header .message-expand-button:insensitive, + .message .message-header .message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #262626; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #1a1a1a, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .icon-button:selected, .login-dialog-button.cancel-button:selected, .login-dialog-button.switch-user-button:selected, .login-dialog-button.login-dialog-session-list-button:selected, .screenshot-ui-show-pointer-button:selected, .message .message-header .message-expand-button:selected, + .message .message-header .message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button:selected, .icon-button:active, .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active, .screenshot-ui-show-pointer-button:active, .message .message-header .message-expand-button:active, + .message .message-header .message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5d5d5d; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 9%), #ffffff, 87%); } + .icon-button:selected:hover, .login-dialog-button.cancel-button:selected:hover, .login-dialog-button.switch-user-button:selected:hover, .login-dialog-button.login-dialog-session-list-button:selected:hover, .screenshot-ui-show-pointer-button:selected:hover, .message .message-header .message-expand-button:selected:hover, + .message .message-header .message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button:selected:hover, .icon-button:active:hover, .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover, .screenshot-ui-show-pointer-button:active:hover, .message .message-header .message-expand-button:active:hover, + .message .message-header .message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button:active:hover { - background-color: #4f4f4f; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 9%), 4%); } + .icon-button:selected:focus, .login-dialog-button.cancel-button:selected:focus, .login-dialog-button.switch-user-button:selected:focus, .login-dialog-button.login-dialog-session-list-button:selected:focus, .screenshot-ui-show-pointer-button:selected:focus, .message .message-header .message-expand-button:selected:focus, + .message .message-header .message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button:selected:focus, .icon-button:active:focus, .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus, .screenshot-ui-show-pointer-button:active:focus, .message .message-header .message-expand-button:active:focus, + .message .message-header .message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button:active:focus { - background-color: #5b5f64; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 9%), #ffffff, 87%), 5%); } + .icon-button:checked, .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked, .screenshot-ui-show-pointer-button:checked, .message .message-header .message-expand-button:checked, + .message .message-header .message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5b5b5b; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), #ffffff, 87%); } + .icon-button:checked:hover, .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .message .message-header .message-expand-button:checked:hover, + .message .message-header .message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button:checked:hover { - background-color: #4d4d4d; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 4%); } + .icon-button:checked:active, .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active, .screenshot-ui-show-pointer-button:checked:active, .message .message-header .message-expand-button:checked:active, + .message .message-header .message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button:checked:active { - background-color: #595959; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 9%); } + +.calendar .calendar-day-heading, .calendar .calendar-day, .calendar .calendar-month-header .calendar-month-label, .icon-button.flat, .flat.login-dialog-button.cancel-button, .flat.login-dialog-button.switch-user-button, .flat.login-dialog-button.login-dialog-session-list-button, .flat.screenshot-ui-show-pointer-button, .message .message-header .flat.message-expand-button, +.message .message-header .flat.message-close-button, .calendar .calendar-month-header .pager-button, .button.flat { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #1a1a1a; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .calendar .calendar-day-heading:focus, .calendar .calendar-day:focus, .calendar .calendar-month-header .calendar-month-label:focus, .icon-button.flat:focus, .flat.login-dialog-button.cancel-button:focus, .flat.login-dialog-button.switch-user-button:focus, .flat.login-dialog-button.login-dialog-session-list-button:focus, .flat.screenshot-ui-show-pointer-button:focus, .message .message-header .flat.message-expand-button:focus, + .message .message-header .flat.message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button.flat:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(33, 54, 80, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(26, 26, 26, 0.25), 5%); } + .calendar .calendar-day-heading:focus:hover, .calendar .calendar-day:focus:hover, .calendar .calendar-month-header .calendar-month-label:focus:hover, .icon-button.flat:focus:hover, .flat.login-dialog-button.cancel-button:focus:hover, .flat.login-dialog-button.switch-user-button:focus:hover, .flat.login-dialog-button.login-dialog-session-list-button:focus:hover, .flat.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .flat.message-expand-button:focus:hover, + .message .message-header .flat.message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button.flat:focus:hover { - background-color: #464a4f; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 7%), #ffffff, 87%), 5%); } + .calendar .calendar-day-heading:hover, .calendar .calendar-day:hover, .calendar .calendar-month-header .calendar-month-label:hover, .icon-button.flat:hover, .flat.login-dialog-button.cancel-button:hover, .flat.login-dialog-button.switch-user-button:hover, .flat.login-dialog-button.login-dialog-session-list-button:hover, .flat.screenshot-ui-show-pointer-button:hover, .message .message-header .flat.message-expand-button:hover, + .message .message-header .flat.message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button.flat:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #474747; } ++ background-color: st-mix(st-lighten(#1a1a1a, 7%), #ffffff, 87%); } + .calendar .calendar-day-heading:insensitive, .calendar .calendar-day:insensitive, .calendar .calendar-month-header .calendar-month-label:insensitive, .icon-button.flat:insensitive, .flat.login-dialog-button.cancel-button:insensitive, .flat.login-dialog-button.switch-user-button:insensitive, .flat.login-dialog-button.login-dialog-session-list-button:insensitive, .flat.screenshot-ui-show-pointer-button:insensitive, .message .message-header .flat.message-expand-button:insensitive, + .message .message-header .flat.message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button.flat:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #1a1a1a; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .calendar .calendar-day-heading:selected, .calendar .calendar-day:selected, .calendar .calendar-month-header .calendar-month-label:selected, .icon-button.flat:selected, .flat.login-dialog-button.cancel-button:selected, .flat.login-dialog-button.switch-user-button:selected, .flat.login-dialog-button.login-dialog-session-list-button:selected, .flat.screenshot-ui-show-pointer-button:selected, .message .message-header .flat.message-expand-button:selected, + .message .message-header .flat.message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button.flat:selected, .calendar .calendar-day-heading:active, .calendar .calendar-day:active, .calendar .calendar-month-header .calendar-month-label:active, .icon-button.flat:active, .flat.login-dialog-button.cancel-button:active, .flat.login-dialog-button.switch-user-button:active, .flat.login-dialog-button.login-dialog-session-list-button:active, .flat.screenshot-ui-show-pointer-button:active, .message .message-header .flat.message-expand-button:active, + .message .message-header .flat.message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button.flat:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #4b4b4b; } ++ background-color: st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%); } + .calendar .calendar-day-heading:selected:hover, .calendar .calendar-day:selected:hover, .calendar .calendar-month-header .calendar-month-label:selected:hover, .icon-button.flat:selected:hover, .flat.login-dialog-button.cancel-button:selected:hover, .flat.login-dialog-button.switch-user-button:selected:hover, .flat.login-dialog-button.login-dialog-session-list-button:selected:hover, .flat.screenshot-ui-show-pointer-button:selected:hover, .message .message-header .flat.message-expand-button:selected:hover, + .message .message-header .flat.message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button.flat:selected:hover, .calendar .calendar-day-heading:active:hover, .calendar .calendar-day:active:hover, .calendar .calendar-month-header .calendar-month-label:active:hover, .icon-button.flat:active:hover, .flat.login-dialog-button.cancel-button:active:hover, .flat.login-dialog-button.switch-user-button:active:hover, .flat.login-dialog-button.login-dialog-session-list-button:active:hover, .flat.screenshot-ui-show-pointer-button:active:hover, .message .message-header .flat.message-expand-button:active:hover, + .message .message-header .flat.message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button.flat:active:hover { - background-color: #424242; } ++ background-color: st-lighten(st-lighten(#1a1a1a, 9%), 7%); } + .calendar .calendar-day-heading:selected:focus, .calendar .calendar-day:selected:focus, .calendar .calendar-month-header .calendar-month-label:selected:focus, .icon-button.flat:selected:focus, .flat.login-dialog-button.cancel-button:selected:focus, .flat.login-dialog-button.switch-user-button:selected:focus, .flat.login-dialog-button.login-dialog-session-list-button:selected:focus, .flat.screenshot-ui-show-pointer-button:selected:focus, .message .message-header .flat.message-expand-button:selected:focus, + .message .message-header .flat.message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button.flat:selected:focus, .calendar .calendar-day-heading:active:focus, .calendar .calendar-day:active:focus, .calendar .calendar-month-header .calendar-month-label:active:focus, .icon-button.flat:active:focus, .flat.login-dialog-button.cancel-button:active:focus, .flat.login-dialog-button.switch-user-button:active:focus, .flat.login-dialog-button.login-dialog-session-list-button:active:focus, .flat.screenshot-ui-show-pointer-button:active:focus, .message .message-header .flat.message-expand-button:active:focus, + .message .message-header .flat.message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button.flat:active:focus { - background-color: #4a4e53; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%), 5%); } + .calendar .calendar-day-heading:checked, .calendar .calendar-day:checked, .calendar .calendar-month-header .calendar-month-label:checked, .icon-button.flat:checked, .flat.login-dialog-button.cancel-button:checked, .flat.login-dialog-button.switch-user-button:checked, .flat.login-dialog-button.login-dialog-session-list-button:checked, .flat.screenshot-ui-show-pointer-button:checked, .message .message-header .flat.message-expand-button:checked, + .message .message-header .flat.message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button.flat:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } ++ background-color: st-mix(st-lighten(#1a1a1a, 8%), #ffffff, 87%); } + .calendar .calendar-day-heading:checked:hover, .calendar .calendar-day:checked:hover, .calendar .calendar-month-header .calendar-month-label:checked:hover, .icon-button.flat:checked:hover, .flat.login-dialog-button.cancel-button:checked:hover, .flat.login-dialog-button.switch-user-button:checked:hover, .flat.login-dialog-button.login-dialog-session-list-button:checked:hover, .flat.screenshot-ui-show-pointer-button:checked:hover, .message .message-header .flat.message-expand-button:checked:hover, + .message .message-header .flat.message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button.flat:checked:hover { - background-color: #404040; } ++ background-color: st-lighten(st-lighten(#1a1a1a, 8%), 7%); } + .calendar .calendar-day-heading:checked:active, .calendar .calendar-day:checked:active, .calendar .calendar-month-header .calendar-month-label:checked:active, .icon-button.flat:checked:active, .flat.login-dialog-button.cancel-button:checked:active, .flat.login-dialog-button.switch-user-button:checked:active, .flat.login-dialog-button.login-dialog-session-list-button:checked:active, .flat.screenshot-ui-show-pointer-button:checked:active, .message .message-header .flat.message-expand-button:checked:active, + .message .message-header .flat.message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button.flat:checked:active { - background-color: #454545; } ++ background-color: st-lighten(st-lighten(#1a1a1a, 8%), 9%); } + +.keyboard-brightness-level .button:checked, .quick-menu-toggle .quick-toggle-arrow:checked, .quick-toggle:checked, .calendar .calendar-day.calendar-today, .icon-button.default, .default.login-dialog-button.cancel-button, .default.login-dialog-button.switch-user-button, .default.login-dialog-button.login-dialog-session-list-button, .default.screenshot-ui-show-pointer-button, .message .message-header .default.message-expand-button, +.message .message-header .default.message-close-button, .calendar .calendar-month-header .default.pager-button, .button.default { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; - color: #ffffff; - background-color: #4f94e8; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(-st-accent-color, #ffffff, 87%); } + .keyboard-brightness-level .button:focus:checked, .quick-menu-toggle .quick-toggle-arrow:focus:checked, .quick-toggle:focus:checked, .calendar .calendar-day.calendar-today:focus, .icon-button.default:focus, .default.login-dialog-button.cancel-button:focus, .default.login-dialog-button.switch-user-button:focus, .default.login-dialog-button.login-dialog-session-list-button:focus, .default.screenshot-ui-show-pointer-button:focus, .message .message-header .default.message-expand-button:focus, + .message .message-header .default.message-close-button:focus, .calendar .calendar-month-header .default.pager-button:focus, .button.default:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; - color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - box-shadow: inset 0 0 0 2px #bcd6f6 !important; - background-color: #4e93e8; } ++ color: -st-accent-fg-color; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ box-shadow: inset 0 0 0 2px st-lighten(-st-accent-color, 30%) !important; ++ background-color: st-mix(-st-accent-color, st-mix(-st-accent-color, #ffffff, 87%), 5%); } + .keyboard-brightness-level .button:focus:hover:checked, .quick-menu-toggle .quick-toggle-arrow:focus:hover:checked, .quick-toggle:focus:hover:checked, .calendar .calendar-day.calendar-today:focus:hover, .icon-button.default:focus:hover, .default.login-dialog-button.cancel-button:focus:hover, .default.login-dialog-button.switch-user-button:focus:hover, .default.login-dialog-button.login-dialog-session-list-button:focus:hover, .default.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .default.message-expand-button:focus:hover, + .message .message-header .default.message-close-button:focus:hover, .calendar .calendar-month-header .default.pager-button:focus:hover, .button.default:focus:hover { - background-color: #5d9dea; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(-st-accent-color, 4%), #ffffff, 87%), 5%); } + .keyboard-brightness-level .button:hover:checked, .quick-menu-toggle .quick-toggle-arrow:hover:checked, .quick-toggle:hover:checked, .calendar .calendar-day.calendar-today:hover, .icon-button.default:hover, .default.login-dialog-button.cancel-button:hover, .default.login-dialog-button.switch-user-button:hover, .default.login-dialog-button.login-dialog-session-list-button:hover, .default.screenshot-ui-show-pointer-button:hover, .message .message-header .default.message-expand-button:hover, + .message .message-header .default.message-close-button:hover, .calendar .calendar-month-header .default.pager-button:hover, .button.default:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; - color: #ffffff; - background-color: #5f9eea; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-lighten(-st-accent-color, 4%), #ffffff, 87%); } + .keyboard-brightness-level .button:insensitive:checked, .quick-menu-toggle .quick-toggle-arrow:insensitive:checked, .quick-toggle:insensitive:checked, .calendar .calendar-day.calendar-today:insensitive, .icon-button.default:insensitive, .default.login-dialog-button.cancel-button:insensitive, .default.login-dialog-button.switch-user-button:insensitive, .default.login-dialog-button.login-dialog-session-list-button:insensitive, .default.screenshot-ui-show-pointer-button:insensitive, .message .message-header .default.message-expand-button:insensitive, + .message .message-header .default.message-close-button:insensitive, .calendar .calendar-month-header .default.pager-button:insensitive, .button.default:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; - color: rgba(255, 255, 255, 0.5); - background-color: #287ce2; ++ color: st-transparentize(-st-accent-fg-color, 0.5); ++ background-color: st-darken(-st-accent-color, 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .keyboard-brightness-level .button:active:checked, .quick-menu-toggle .quick-toggle-arrow:active:checked, .quick-toggle:active:checked, .calendar .calendar-day.calendar-today:active, .icon-button.default:active, .default.login-dialog-button.cancel-button:active, .default.login-dialog-button.switch-user-button:active, .default.login-dialog-button.login-dialog-session-list-button:active, .default.screenshot-ui-show-pointer-button:active, .message .message-header .default.message-expand-button:active, + .message .message-header .default.message-close-button:active, .calendar .calendar-month-header .default.pager-button:active, .button.default:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; - color: #ffffff; - background-color: #72a9ec; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-lighten(-st-accent-color, 9%), #ffffff, 87%); } + .keyboard-brightness-level .button:active:hover:checked, .quick-menu-toggle .quick-toggle-arrow:active:hover:checked, .quick-toggle:active:hover:checked, .calendar .calendar-day.calendar-today:active:hover, .icon-button.default:active:hover, .default.login-dialog-button.cancel-button:active:hover, .default.login-dialog-button.switch-user-button:active:hover, .default.login-dialog-button.login-dialog-session-list-button:active:hover, .default.screenshot-ui-show-pointer-button:active:hover, .message .message-header .default.message-expand-button:active:hover, + .message .message-header .default.message-close-button:active:hover, .calendar .calendar-month-header .default.pager-button:active:hover, .button.default:active:hover { - background-color: #6fa8ec; } ++ background-color: st-lighten(st-lighten(-st-accent-color, 9%), 4%); } + .keyboard-brightness-level .button:active:focus:checked, .quick-menu-toggle .quick-toggle-arrow:active:focus:checked, .quick-toggle:active:focus:checked, .calendar .calendar-day.calendar-today:active:focus, .icon-button.default:active:focus, .default.login-dialog-button.cancel-button:active:focus, .default.login-dialog-button.switch-user-button:active:focus, .default.login-dialog-button.login-dialog-session-list-button:active:focus, .default.screenshot-ui-show-pointer-button:active:focus, .message .message-header .default.message-expand-button:active:focus, + .message .message-header .default.message-close-button:active:focus, .calendar .calendar-month-header .default.pager-button:active:focus, .button.default:active:focus { - background-color: #6fa7ec; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(-st-accent-color, 9%), #ffffff, 87%), 5%); } + +.popup-sub-menu .popup-menu-item, .popup-menu-item { + font-weight: normal; + spacing: 6px; + transition-duration: 100ms; + padding: 9px 12px; } + - .calendar, .datemenu-today-button, .lg-extension, .quick-toggle-menu, .message, .events-button, ++#LookingGlassExtensions .lg-extension, #LookingGlassWindows .lg-window, .calendar, .datemenu-today-button, .quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + border-radius: 12px; + padding: 0.818em; + margin: 4px; + background-color: #1a1a1a; + box-shadow: 0 1px 2px 0 transparent; + border: 1px solid #1a1a1a; + border-color: transparent; + box-shadow: none; } + - .lg-extension, .quick-toggle-menu, .message, .events-button, ++.quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #373737; } - .lg-extension:hover, .quick-toggle-menu:hover, .message:hover, .events-button:hover, ++ background-color: st-mix(#1a1a1a, #ffffff, 87%); } ++ .quick-toggle-menu:hover, .message:hover, .events-button:hover, + .world-clocks-button:hover, + .weather-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #404040; } - .lg-extension:active, .quick-toggle-menu:active, .message:active, .events-button:active, ++ background-color: st-mix(st-lighten(#1a1a1a, 4%), #ffffff, 87%); } ++ .quick-toggle-menu:active, .message:active, .events-button:active, + .world-clocks-button:active, + .weather-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #4b4b4b; } - .lg-extension:active:hover, .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, ++ background-color: st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%); } ++ .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, + .world-clocks-button:active:hover, + .weather-button:active:hover { - background-color: #3b3b3b; } - .lg-extension:active:focus, .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, ++ background-color: st-lighten(st-lighten(#1a1a1a, 9%), 4%); } ++ .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, + .world-clocks-button:active:focus, + .weather-button:active:focus { - background-color: #4a4e53; } - .lg-extension:focus, .quick-toggle-menu:focus, .message:focus, .events-button:focus, ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%), 5%); } ++ .quick-toggle-menu:focus, .message:focus, .events-button:focus, + .world-clocks-button:focus, + .weather-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #373b40; } - .lg-extension:focus:hover, .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#1a1a1a, #ffffff, 87%), 5%); } ++ .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, + .world-clocks-button:focus:hover, + .weather-button:focus:hover { - background-color: #3f4348; } - .lg-extension:insensitive, .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 4%), #ffffff, 87%), 5%); } ++ .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, + .world-clocks-button:insensitive, + .weather-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #121212; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(#1a1a1a, 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + +.calendar, .datemenu-today-button { + border: 1px solid transparent !important; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .calendar:insensitive, .datemenu-today-button:insensitive { + background-color: transparent !important; } + .calendar:hover, .datemenu-today-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #474747; } ++ background-color: st-mix(st-lighten(#1a1a1a, 7%), #ffffff, 87%); } + .calendar:active, .datemenu-today-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #4b4b4b; } ++ background-color: st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%); } + .calendar:active:hover, .datemenu-today-button:active:hover { - background-color: #424242; } ++ background-color: st-lighten(st-lighten(#1a1a1a, 9%), 7%); } + .calendar:active:focus, .datemenu-today-button:active:focus { - background-color: #4a4e53; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 9%), #ffffff, 87%), 5%); } + .calendar:focus, .datemenu-today-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #373b40; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#1a1a1a, #ffffff, 87%), 5%); } + .calendar:focus:hover, .datemenu-today-button:focus:hover { - background-color: #3f4348; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#1a1a1a, 4%), #ffffff, 87%), 5%); } + .calendar:insensitive, .datemenu-today-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #121212; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(#1a1a1a, 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + +.unlock-dialog .login-dialog-prompt-entry, .login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry, .lg-dialog StEntry, StEntry { + border-radius: 8px; + padding: 9px 9px; - selection-background-color: #3584e4; ++ selection-background-color: st-transparentize(-st-accent-color, 0.7); + selected-color: #ffffff; } + +StEntry { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #2e2e2e; + color: rgba(255, 255, 255, 0.7); } + StEntry:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #383838; + color: #ffffff; } + StEntry:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #2e3237; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, #2e2e2e, 5%); + color: #ffffff; } + StEntry:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #262626; + color: rgba(255, 255, 255, 0.5); } + StEntry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + - .modal-dialog .modal-dialog-linked-button, .notification-button { ++.notification-button, .message .message-header .message-expand-button, ++.message .message-header .message-close-button { ++ font-weight: bold; ++ padding: 6px 12px; ++ border-radius: 8px; ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(rgba(255, 255, 255, 0.15), #ffffff, 87%); } ++ .notification-button:focus, .message .message-header .message-expand-button:focus, ++ .message .message-header .message-close-button:focus { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.15), #ffffff, 87%), 5%); } ++ .notification-button:focus:hover, .message .message-header .message-expand-button:focus:hover, ++ .message .message-header .message-close-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.3), #ffffff, 87%), 5%); } ++ .notification-button:hover, .message .message-header .message-expand-button:hover, ++ .message .message-header .message-close-button:hover { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(rgba(255, 255, 255, 0.3), #ffffff, 87%); } ++ .notification-button:active, .message .message-header .message-expand-button:active, ++ .message .message-header .message-close-button:active { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(rgba(255, 255, 255, 0.2), #ffffff, 87%); } ++ .notification-button:active:hover, .message .message-header .message-expand-button:active:hover, ++ .message .message-header .message-close-button:active:hover { ++ background-color: rgba(255, 255, 255, 0.2); } ++ .notification-button:active:focus, .message .message-header .message-expand-button:active:focus, ++ .message .message-header .message-close-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.2), #ffffff, 87%), 5%); } ++ .notification-button:checked, .message .message-header .message-expand-button:checked, ++ .message .message-header .message-close-button:checked { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), #ffffff, 87%); } ++ .notification-button:checked:hover, .message .message-header .message-expand-button:checked:hover, ++ .message .message-header .message-close-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 4%); } ++ .notification-button:checked:active, .message .message-header .message-expand-button:checked:active, ++ .message .message-header .message-close-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 9%); } ++ .notification-button:insensitive, .message .message-header .message-expand-button:insensitive, ++ .message .message-header .message-close-button:insensitive { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: rgba(255, 255, 255, 0.1); ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ box-shadow: none; ++ border: none; } ++ ++.modal-dialog .modal-dialog-linked-button { ++ font-weight: bold; + padding: 12px; - font-weight: bold !important; ++ border-radius: 12px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.217); } - .modal-dialog .modal-dialog-linked-button:ltr, .notification-button:ltr { - margin-right: 1px; } - .modal-dialog .modal-dialog-linked-button:rtl, .notification-button:rtl { - margin-left: 1px; } - .modal-dialog .modal-dialog-linked-button:focus, .notification-button:focus { ++ background-color: st-mix(rgba(255, 255, 255, 0.1), #ffffff, 87%); } ++ .modal-dialog .modal-dialog-linked-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(194, 218, 247, 0.25615); } - .modal-dialog .modal-dialog-linked-button:focus:hover, .notification-button:focus:hover { - background-color: rgba(199, 221, 248, 0.280945); } - .modal-dialog .modal-dialog-linked-button:hover, .notification-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.1), #ffffff, 87%), 5%); } ++ .modal-dialog .modal-dialog-linked-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.13), #ffffff, 87%), 5%); } ++ .modal-dialog .modal-dialog-linked-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.2431); } - .modal-dialog .modal-dialog-linked-button:active, .notification-button:active { ++ background-color: st-mix(rgba(255, 255, 255, 0.13), #ffffff, 87%); } ++ .modal-dialog .modal-dialog-linked-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.2692); } - .modal-dialog .modal-dialog-linked-button:active:hover, .notification-button:active:hover { ++ background-color: st-mix(rgba(255, 255, 255, 0.16), #ffffff, 87%); } ++ .modal-dialog .modal-dialog-linked-button:active:hover { + background-color: rgba(255, 255, 255, 0.19); } - .modal-dialog .modal-dialog-linked-button:active:focus, .notification-button:active:focus { - background-color: rgba(204, 224, 248, 0.30574); } - .modal-dialog .modal-dialog-linked-button:checked, .notification-button:checked { ++ .modal-dialog .modal-dialog-linked-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.16), #ffffff, 87%), 5%); } ++ .modal-dialog .modal-dialog-linked-button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5b5b5b; } - .modal-dialog .modal-dialog-linked-button:checked:hover, .notification-button:checked:hover { - background-color: #4d4d4d; } - .modal-dialog .modal-dialog-linked-button:checked:active, .notification-button:checked:active { - background-color: #595959; } - .modal-dialog .modal-dialog-linked-button:insensitive, .notification-button:insensitive { ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), #ffffff, 87%); } ++ .modal-dialog .modal-dialog-linked-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 4%); } ++ .modal-dialog .modal-dialog-linked-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 9%); } ++ .modal-dialog .modal-dialog-linked-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #262626; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #1a1a1a, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } - .modal-dialog .modal-dialog-linked-button:first-child:ltr, .notification-button:first-child:ltr { - border-radius: 0 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:ltr, .notification-button:last-child:ltr { - border-radius: 0 0 15px; - margin-right: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:rtl, .notification-button:first-child:rtl { - border-radius: 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:rtl, .notification-button:last-child:rtl { - border-radius: 0 0 0 15px; - margin-left: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:last-child, .notification-button:first-child:last-child { - border-radius: 0 0 15px 15px; - margin-left: 0 !important; - margin-right: 0 !important; } + +.dash-label, .window-caption, .screenshot-ui-tooltip { + background-color: rgba(0, 0, 0, 0.9); + border: 1px solid rgba(255, 255, 255, 0.1); + color: #ffffff; + border-radius: 999px; + padding: 6px 12px; + text-align: center; + background-color: black; + border-color: rgba(255, 255, 255, 0.4); } + +/* General Typography */ - .login-dialog .user-widget.vertical .user-widget-label, - .unlock-dialog .user-widget.vertical .user-widget-label, .unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { ++.unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { + font-weight: 800; + font-size: 1.818em; } + - .conflicting-session-dialog-content .conflicting-session-dialog-title, .lg-debug-flags-header, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { ++.conflicting-session-dialog-content .conflicting-session-dialog-title, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { + font-weight: 800; + font-size: 1.364em; } + +.login-dialog .user-widget.horizontal .user-widget-label, +.unlock-dialog .user-widget.horizontal .user-widget-label, .quick-toggle-menu .header .title { + font-weight: 700; + font-size: 1.364em; } + - .login-dialog-auth-list-label, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { ++.login-dialog-auth-list-label, #LookingGlassDebugFlags .lg-debug-flags-header, #LookingGlassExtensions .lg-extensions-none, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { + font-weight: 700; + font-size: 1.182em; } + - .login-dialog-not-listed-label, .lg-extension-name, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { ++.login-dialog-not-listed-label, #LookingGlassExtensions .lg-extension .lg-extension-name, #LookingGlassWindows .lg-window .lg-window-name, #LookingGlassPropertyInspector .lg-obj-inspector-title, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { + font-weight: 700; + font-size: 1em; } + +.quick-toggle-menu .header .subtitle, .app-menu .popup-inactive-menu-item:first-child > StLabel { + font-weight: 700; + font-size: 0.818em; } + +.lg-completions-text, .caps-lock-warning-label, .background-app-item .subtitle, .quick-toggle StBoxLayout > .quick-toggle-subtitle, .screenshot-ui-type-button .icon-label-button-container, .prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label, .run-dialog .run-dialog-description, .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description, .message .message-header .message-header-content .event-time, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .events-button .events-box .events-list .event-box .event-time { + font-weight: 400; + font-size: 0.818em; } + +.weather-button .weather-box .weather-grid .weather-forecast-time, .calendar .calendar-week-number, .calendar .calendar-day-heading, .calendar .calendar-day { + font-weight: 400; + font-size: 0.818em; } + - #EvalBox { ++#LookingGlassDebugFlags .lg-debug-flag-button StLabel, #LookingGlassEvaluator .evaluator-results, .lg-dialog .actor-link { + font-family: monospace; } + +.unlock-dialog-clock .unlock-dialog-clock-time, #panel, .weather-button .weather-box .weather-grid .weather-forecast-temp, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .world-clocks-button .world-clocks-grid .world-clocks-time, .events-button .events-box .events-list .event-box .event-time, .calendar .calendar-day-heading, .calendar .calendar-day { + font-feature-settings: "tnum"; } + +/* OSD Elements */ +#LookingGlassDialog, .screenshot-ui-panel, .workspace-switcher, .switcher-list, .resize-popup, .osd-window { + color: #ffffff; + background-color: #000000; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 999px; + padding: 12px; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.4); + border: 2px solid rgba(255, 255, 255, 0.4); + box-shadow: none; } + +.lg-dialog StEntry { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #171717; + color: rgba(255, 255, 255, 0.7); } + .lg-dialog StEntry:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #212121; + color: #ffffff; } + .lg-dialog StEntry:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #191c21; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, #171717, 5%); + color: #ffffff; } + .lg-dialog StEntry:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #0f0f0f; + color: rgba(255, 255, 255, 0.5); } + .lg-dialog StEntry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + - #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button { ++#LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } - #LookingGlassDialog .notebook-tab:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { ++ background-color: st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #35393e; } - #LookingGlassDialog .notebook-tab:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { - background-color: #3e4246; } - #LookingGlassDialog .notebook-tab:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #3e3e3e; } - #LookingGlassDialog .notebook-tab:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } - #LookingGlassDialog .notebook-tab:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { - background-color: #383838; } - #LookingGlassDialog .notebook-tab:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { - background-color: #484c51; } - #LookingGlassDialog .notebook-tab:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #474747; } - #LookingGlassDialog .notebook-tab:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { - background-color: #363636; } - #LookingGlassDialog .notebook-tab:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { - background-color: #424242; } - #LookingGlassDialog .notebook-tab:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), #ffffff, 87%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:insensitive, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:insensitive, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #0f0f0f; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #000000, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + - .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { ++#LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } - .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { ++ #LookingGlassDialog .notebook-tab:focus, .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(14, 36, 61, 0.2875); } - .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { - background-color: #31353a; } - .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(0, 0, 0, 0.25), 5%); } ++ #LookingGlassDialog .notebook-tab:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 7%), #ffffff, 87%), 5%); } ++ #LookingGlassDialog .notebook-tab:hover, .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #313131; } - .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { ++ background-color: st-mix(st-lighten(#000000, 7%), #ffffff, 87%); } ++ #LookingGlassDialog .notebook-tab:active, .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } - .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { - background-color: #292929; } - .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { - background-color: #35393e; } - .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { ++ background-color: st-mix(st-lighten(#000000, 9%), #ffffff, 87%); } ++ #LookingGlassDialog .notebook-tab:active:hover, .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { ++ background-color: st-lighten(st-lighten(#000000, 9%), 7%); } ++ #LookingGlassDialog .notebook-tab:active:focus, .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 9%), #ffffff, 87%), 5%); } ++ #LookingGlassDialog .notebook-tab:checked, .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #333333; } - .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { - background-color: #262626; } - .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { - background-color: #2b2b2b; } - .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { ++ background-color: st-mix(st-lighten(#000000, 8%), #ffffff, 87%); } ++ #LookingGlassDialog .notebook-tab:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { ++ background-color: st-lighten(st-lighten(#000000, 8%), 7%); } ++ #LookingGlassDialog .notebook-tab:checked:active, .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { ++ background-color: st-lighten(st-lighten(#000000, 8%), 9%); } ++ #LookingGlassDialog .notebook-tab:insensitive, .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + +/* System Elements */ +.login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #232323; + color: rgba(255, 255, 255, 0.7); } + .login-dialog .login-dialog-prompt-entry:hover, .app-folder-dialog .folder-name-container .folder-name-entry:hover, .search-entry:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #2d2d2d; + color: #ffffff; } + .login-dialog .login-dialog-prompt-entry:focus, .app-folder-dialog .folder-name-container .folder-name-entry:focus, .search-entry:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #24282d; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, #232323, 5%); + color: #ffffff; } + .login-dialog .login-dialog-prompt-entry:insensitive, .app-folder-dialog .folder-name-container .folder-name-entry:insensitive, .search-entry:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: #1b1b1b; + color: rgba(255, 255, 255, 0.5); } + .login-dialog .login-dialog-prompt-entry StLabel.hint-text, .app-folder-dialog .folder-name-container .folder-name-entry StLabel.hint-text, .search-entry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + +.login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #404040; } ++ background-color: st-mix(st-mix(#ffffff, #0d0d0d, 9%), #ffffff, 87%); } + .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #1b1b1b; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #0d0d0d, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #3f4348; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #0d0d0d, 9%), #ffffff, 87%), 5%); } + .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: #474b50; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 4%), #ffffff, 87%), 5%); } + .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #484848; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 4%), #ffffff, 87%); } + .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #545454; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 9%), #ffffff, 87%); } + .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover { - background-color: #444444; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 9%), 4%); } + .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: #52565b; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 9%), #ffffff, 87%), 5%); } + .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #515151; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 8%), #ffffff, 87%); } + .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #424242; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 8%), 4%); } + .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #0d0d0d, 9%), 8%), 9%); } + +/* Lockscreen Elements */ +.unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .calendar .calendar-month-header .pager-button, +.calendar .calendar-month-header .unlock-dialog .pager-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, +.unlock-dialog .screenshot-ui-show-pointer-button, +.unlock-dialog .login-dialog-button.cancel-button, +.unlock-dialog .login-dialog-button.switch-user-button, +.unlock-dialog .login-dialog-button.login-dialog-session-list-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.217); } ++ background-color: st-mix(rgba(255, 255, 255, 0.1), #ffffff, 87%); } + .unlock-dialog .button:focus, + .unlock-dialog .icon-button:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus, + .unlock-dialog .message .message-header .message-expand-button:focus, + .message .message-header .unlock-dialog .message-expand-button:focus, + .unlock-dialog .message .message-header .message-close-button:focus, + .message .message-header .unlock-dialog .message-close-button:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:focus, + .unlock-dialog .login-dialog-button.cancel-button:focus, + .unlock-dialog .login-dialog-button.switch-user-button:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(194, 218, 247, 0.25615); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.1), #ffffff, 87%), 5%); } + .unlock-dialog .button:focus:hover, + .unlock-dialog .icon-button:focus:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus:hover, + .unlock-dialog .message .message-header .message-expand-button:focus:hover, + .message .message-header .unlock-dialog .message-expand-button:focus:hover, + .unlock-dialog .message .message-header .message-close-button:focus:hover, + .message .message-header .unlock-dialog .message-close-button:focus:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:focus:hover, + .unlock-dialog .login-dialog-button.cancel-button:focus:hover, + .unlock-dialog .login-dialog-button.switch-user-button:focus:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: rgba(199, 221, 248, 0.280945); } ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.13), #ffffff, 87%), 5%); } + .unlock-dialog .button:hover, + .unlock-dialog .icon-button:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:hover, + .unlock-dialog .message .message-header .message-expand-button:hover, + .message .message-header .unlock-dialog .message-expand-button:hover, + .unlock-dialog .message .message-header .message-close-button:hover, + .message .message-header .unlock-dialog .message-close-button:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:hover, + .unlock-dialog .login-dialog-button.cancel-button:hover, + .unlock-dialog .login-dialog-button.switch-user-button:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.2431); } ++ background-color: st-mix(rgba(255, 255, 255, 0.13), #ffffff, 87%); } + .unlock-dialog .button:active, + .unlock-dialog .icon-button:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:active, + .unlock-dialog .message .message-header .message-expand-button:active, + .message .message-header .unlock-dialog .message-expand-button:active, + .unlock-dialog .message .message-header .message-close-button:active, + .message .message-header .unlock-dialog .message-close-button:active, + .unlock-dialog .screenshot-ui-show-pointer-button:active, + .unlock-dialog .login-dialog-button.cancel-button:active, + .unlock-dialog .login-dialog-button.switch-user-button:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: rgba(255, 255, 255, 0.2692); } ++ background-color: st-mix(rgba(255, 255, 255, 0.16), #ffffff, 87%); } + .unlock-dialog .button:active:hover, + .unlock-dialog .icon-button:active:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:hover, + .unlock-dialog .message .message-header .message-expand-button:active:hover, + .message .message-header .unlock-dialog .message-expand-button:active:hover, + .unlock-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .unlock-dialog .message-close-button:active:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:active:hover, + .unlock-dialog .login-dialog-button.cancel-button:active:hover, + .unlock-dialog .login-dialog-button.switch-user-button:active:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:hover { + background-color: rgba(255, 255, 255, 0.19); } + .unlock-dialog .button:active:focus, + .unlock-dialog .icon-button:active:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:focus, + .unlock-dialog .message .message-header .message-expand-button:active:focus, + .message .message-header .unlock-dialog .message-expand-button:active:focus, + .unlock-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .unlock-dialog .message-close-button:active:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:active:focus, + .unlock-dialog .login-dialog-button.cancel-button:active:focus, + .unlock-dialog .login-dialog-button.switch-user-button:active:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: rgba(204, 224, 248, 0.30574); } ++ background-color: st-mix(-st-accent-color, st-mix(rgba(255, 255, 255, 0.16), #ffffff, 87%), 5%); } + .unlock-dialog .button:checked, + .unlock-dialog .icon-button:checked, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked, + .unlock-dialog .message .message-header .message-expand-button:checked, + .message .message-header .unlock-dialog .message-expand-button:checked, + .unlock-dialog .message .message-header .message-close-button:checked, + .message .message-header .unlock-dialog .message-close-button:checked, + .unlock-dialog .screenshot-ui-show-pointer-button:checked, + .unlock-dialog .login-dialog-button.cancel-button:checked, + .unlock-dialog .login-dialog-button.switch-user-button:checked, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5b5b5b; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), #ffffff, 87%); } + .unlock-dialog .button:checked:hover, + .unlock-dialog .icon-button:checked:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:hover, + .unlock-dialog .message .message-header .message-expand-button:checked:hover, + .message .message-header .unlock-dialog .message-expand-button:checked:hover, + .unlock-dialog .message .message-header .message-close-button:checked:hover, + .message .message-header .unlock-dialog .message-close-button:checked:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:hover, + .unlock-dialog .login-dialog-button.cancel-button:checked:hover, + .unlock-dialog .login-dialog-button.switch-user-button:checked:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #4d4d4d; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 4%); } + .unlock-dialog .button:checked:active, + .unlock-dialog .icon-button:checked:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:active, + .unlock-dialog .message .message-header .message-expand-button:checked:active, + .message .message-header .unlock-dialog .message-expand-button:checked:active, + .unlock-dialog .message .message-header .message-close-button:checked:active, + .message .message-header .unlock-dialog .message-close-button:checked:active, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:active, + .unlock-dialog .login-dialog-button.cancel-button:checked:active, + .unlock-dialog .login-dialog-button.switch-user-button:checked:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #595959; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 8%), 9%); } + .unlock-dialog .button:insensitive, + .unlock-dialog .icon-button:insensitive, + .unlock-dialog .calendar .calendar-month-header .pager-button:insensitive, + .calendar .calendar-month-header .unlock-dialog .pager-button:insensitive, + .unlock-dialog .message .message-header .message-expand-button:insensitive, + .message .message-header .unlock-dialog .message-expand-button:insensitive, + .unlock-dialog .message .message-header .message-close-button:insensitive, + .message .message-header .unlock-dialog .message-close-button:insensitive, + .unlock-dialog .screenshot-ui-show-pointer-button:insensitive, + .unlock-dialog .login-dialog-button.cancel-button:insensitive, + .unlock-dialog .login-dialog-button.switch-user-button:insensitive, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #262626; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #1a1a1a, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + +.unlock-dialog .login-dialog-prompt-entry { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.7); } + .unlock-dialog .login-dialog-prompt-entry:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: rgba(255, 255, 255, 0.1); + color: #ffffff; } + .unlock-dialog .login-dialog-prompt-entry:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(154, 194, 242, 0.145); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(255, 255, 255, 0.1), 5%); + color: #ffffff; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.7) !important; - background-color: rgba(255, 255, 255, 0.13); } ++ background-color: st-mix(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.1), 5%); } + .unlock-dialog .login-dialog-prompt-entry:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: rgba(247, 247, 247, 0.1); + color: rgba(255, 255, 255, 0.5); } + .unlock-dialog .login-dialog-prompt-entry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + +/* WIDGETS */ +.shell-link { - color: #62a0ea; } ++ color: st-lighten(-st-accent-color, 20%); } + .shell-link:hover { - color: #8fbbf0; } ++ color: st-lighten(st-lighten(-st-accent-color, 20%), 10%); } + +.lowres-icon { + icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } + +.icon-dropshadow { + icon-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); + icon-shadow: none; } + +/* Entries */ +StEntry StIcon.capslock-warning { + icon-size: 1.091em; + warning-color: #f6d32d; + padding: 0 4px; } + +StEntry StIcon.peek-password { + icon-size: 1.091em; + padding: 0 4px; } + +StEntry StLabel.hint-text { + margin-left: 2px; } + +/* Buttons */ +.button { + min-height: 1.5em; } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button { + border-radius: 999px; + padding: 0.818em; + min-height: 1.091em; } + .icon-button StIcon, .login-dialog-button.cancel-button StIcon, .login-dialog-button.switch-user-button StIcon, .login-dialog-button.login-dialog-session-list-button StIcon, .screenshot-ui-show-pointer-button StIcon, .message .message-header .message-expand-button StIcon, + .message .message-header .message-close-button StIcon, .calendar .calendar-month-header .pager-button StIcon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + +/* Check Boxes */ +.check-box StBoxLayout { + spacing: .8em; } + +.check-box StBin { - width: 24px; - height: 24px; - background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); } ++ border-radius: 7px; ++ padding: 2px; } + +.check-box:focus StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); } ++ background-color: rgba(0, 0, 0, 0.01); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.65); } ++ ++.check-box StIcon { ++ icon-size: 14px; ++ padding: 1px; ++ color: transparent; ++ border-radius: 6px; ++ border: 2px solid rgba(255, 255, 255, 0.15); } ++ ++.check-box:hover StIcon { ++ border-color: rgba(255, 255, 255, 0.2); } ++ ++.check-box:active StIcon { ++ border-color: rgba(255, 255, 255, 0.3); } + - .check-box:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); } ++.check-box:checked StIcon { ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; ++ border-color: transparent; } + - .check-box:focus:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); } ++.check-box:checked:hover StIcon { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } ++ ++.check-box:checked:active StIcon { ++ background-color: st-darken(-st-accent-color, 7%); ++ color: st-darken(-st-accent-fg-color, 7%); } + +/* Switches */ +.toggle-switch { - color: #ffffff; - height: 26px; + width: 46px; - background-size: contain; - background-image: url("resource:///org/gnome/shell/theme/toggle-off.svg"); } - .toggle-switch:checked { - background-image: url("resource:///org/gnome/shell/theme/toggle-on.svg"); } ++ border-radius: 999px; ++ transition-duration: 100ms; ++ color: #ffffff; ++ background: rgba(255, 255, 255, 0.3); } ++ .toggle-switch:hover { ++ background: rgba(255, 255, 255, 0.4); } + .toggle-switch StIcon { + icon-size: 16px; } ++ .toggle-switch .handle { ++ margin: 3px; ++ width: 20px; ++ height: 20px; ++ border-radius: 999px; ++ background: #d1d1d1; ++ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); ++ transition-duration: 100ms; } ++ .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } ++ .toggle-switch:checked .handle { ++ background: white; } + +/* Slider */ +.slider { ++ color: #e8e8e8; + -barlevel-height: 4px; - -barlevel-background-color: rgba(255, 255, 255, 0.2); - -barlevel-border-width: 2px; - -barlevel-border-color: transparent; - -barlevel-active-background-color: #3584e4; - -barlevel-active-border-color: transparent; ++ -barlevel-background-color: rgba(255, 255, 255, 0.1); ++ -barlevel-active-background-color: -st-accent-color; + -barlevel-overdrive-color: #c01c28; - -barlevel-overdrive-border-color: transparent; + -barlevel-overdrive-separator-width: 1px; + -slider-handle-radius: 0.5455em; - -slider-handle-border-width: 0; - -slider-handle-border-color: transparent; + -barlevel-background-color: rgba(255, 255, 255, 0.4); } ++ .slider:hover { ++ color: #ffffff; } + +/* Scrollbars */ +StScrollView.vfade { + -st-vfade-offset: 68px; } + +StScrollView.hfade { + -st-hfade-offset: 68px; } + +StScrollBar { + padding: 0; } + StScrollView StScrollBar { + min-width: 8px; + min-height: 8px; } + StScrollBar StBin#trough { + border-radius: 0; + background-color: transparent; } + StScrollBar StButton#vhandle, StScrollBar StButton#hhandle { + border-radius: 8px; + background-color: #5e5e5e; + border: 3px solid transparent; + transition: 500ms all ease; } + StScrollBar StButton#vhandle:hover, StScrollBar StButton#hhandle:hover { + background-color: #8c8c8c; } + StScrollBar StButton#vhandle:active, StScrollBar StButton#hhandle:active { + background-color: #757575; } + +/* Popovers/Menus */ +.popup-menu-boxpointer, .candidate-popup-boxpointer { + -arrow-rise: 6px; } + +.popup-menu { + min-width: 15em; + color: #ffffff; } + .popup-menu.panel-menu { + margin-bottom: 1.75em; } + +.popup-menu-content, .candidate-popup-content { + padding: 6px; + background-color: #1a1a1a; + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.5); + box-shadow: 0 2px 4px 0 transparent; } + +.popup-menu-item { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: transparent; + border-color: transparent; + box-shadow: none; + border-radius: 12px; } + .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-menu-item:focus, .popup-menu-item:hover { ++ .popup-menu-item:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5c5c5c; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #262626, 9%), 4%), #ffffff, 87%); } + .popup-menu-item:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #686868; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #262626, 9%), 9%), #ffffff, 87%); } + .popup-menu-item:active:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #262626, 9%), 9%), 4%); } + .popup-menu-item:active:focus { - background-color: #65696e; } - .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #262626, 9%), 9%), #ffffff, 87%), 5%); } ++ .popup-menu-item:selected, .popup-menu-item:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #656565; } - .popup-menu-item:checked:hover { - background-color: #595959; } - .popup-menu-item:checked:active { - background-color: #656565; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #262626, 9%), 8%), #ffffff, 87%); } ++ .popup-menu-item:selected:hover, .popup-menu-item:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #262626, 9%), 8%), 4%); } ++ .popup-menu-item:selected:active, .popup-menu-item:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #262626, 9%), 8%), 9%); } + .popup-menu-item:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #323232; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #262626, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .popup-menu-item:checked { + border-radius: 12px 12px 0 0 !important; + border: 1px solid rgba(255, 255, 255, 0.4); + border-bottom-width: 0; } + .popup-menu-item .toggle-switch:ltr { + margin-left: 4px; } + .popup-menu-item .toggle-switch:rtl { + margin-right: 4px; } + +.popup-ornamented-menu-item:ltr { + padding-left: 6px; } + +.popup-ornamented-menu-item:rtl { + padding-right: 6px; } + +.popup-inactive-menu-item { + color: #ffffff; } + .popup-inactive-menu-item:insensitive { + color: #ffffff; } + +.popup-menu-arrow, +.popup-menu-icon { + icon-size: 1.091em; } + +.popup-sub-menu { + border-radius: 0 0 13px 13px; + margin-bottom: 6px; + border: 1px solid transparent; + background-color: #3b3b3b; + border-color: rgba(255, 255, 255, 0.4); } + .popup-sub-menu .popup-menu-item { + border-radius: 0; + border-top-width: 0; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .popup-sub-menu .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-sub-menu .popup-menu-item:focus, .popup-sub-menu .popup-menu-item:hover { ++ .popup-sub-menu .popup-menu-item:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #6c6c6c; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 4%), #ffffff, 87%); } + .popup-sub-menu .popup-menu-item:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #777777; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 9%), #ffffff, 87%); } + .popup-sub-menu .popup-menu-item:active:hover { - background-color: #6d6d6d; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 9%), 4%); } + .popup-sub-menu .popup-menu-item:active:focus { - background-color: #74787c; } - .popup-sub-menu .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 9%), #ffffff, 87%), 5%); } ++ .popup-sub-menu .popup-menu-item:selected, .popup-sub-menu .popup-menu-item:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #757575; } - .popup-sub-menu .popup-menu-item:checked:hover { - background-color: #6b6b6b; } - .popup-sub-menu .popup-menu-item:checked:active { - background-color: #777777; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 8%), #ffffff, 87%); } ++ .popup-sub-menu .popup-menu-item:selected:hover, .popup-sub-menu .popup-menu-item:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 8%), 4%); } ++ .popup-sub-menu .popup-menu-item:selected:active, .popup-sub-menu .popup-menu-item:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #3b3b3b, 9%), 8%), 9%); } + .popup-sub-menu .popup-menu-item:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #444444; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #3b3b3b, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .popup-sub-menu .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; + border-bottom-width: 0; } + .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:hover, .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:focus { + border-radius: 0; } + .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; } + +.popup-menu-ornament { + icon-size: 1.091em !important; + width: 1.091em; } + +.popup-separator-menu-item { + border: none !important; } + .popup-separator-menu-item .popup-separator-menu-item-separator { + height: 1px; + background-color: rgba(255, 255, 255, 0.5); } + .popup-sub-menu .popup-separator-menu-item { + background-color: transparent; } + .popup-sub-menu .popup-separator-menu-item:ltr { + margin-right: 2.5em; } + .popup-sub-menu .popup-separator-menu-item:rtl { + margin-left: 2.5em; } + .popup-sub-menu .popup-separator-menu-item .popup-separator-menu-item-separator { + background-color: rgba(255, 255, 255, 0.5); } + +.background-menu { + -boxpointer-gap: 0px; + -arrow-rise: 0px; } + +.app-menu { + max-width: 27.25em; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:ltr { + margin-right: 8px; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:rtl { + margin-left: 8px; } + +/* Date/Time Menu */ +#calendarArea { + padding: 4px; } + +.datemenu-popover { + border-radius: 30px; } + +.datemenu-calendar-column { + spacing: 6px; } + .datemenu-calendar-column:ltr { + margin-left: 6px; } + .datemenu-calendar-column:rtl { + margin-right: 6px; } + .datemenu-calendar-column .datemenu-displays-box { + spacing: 6px; } + +.datemenu-today-button { + padding: 9px; } + .datemenu-today-button .day-label { + font-weight: bold; } + +.calendar { + margin-top: 0; + padding: 0; } + .calendar .calendar-month-header .calendar-change-month-back StIcon, + .calendar .calendar-month-header .calendar-change-month-forward StIcon { + icon-size: 1.091em; } + .calendar .calendar-month-header .calendar-month-label { + color: #ffffff !important; + padding: 8px 0; + width: 10em; + border-radius: 999px; + text-align: center; } + .calendar .calendar-month-header .pager-button { + height: 2.6em; + width: 2.6em; + padding: 0; } + .calendar .calendar-day { + border-radius: 999px; + height: 3em; + width: 3em; + margin: 2px; + padding: 0; + font-weight: bold; + text-align: center; } + .calendar .calendar-day.calendar-weekend { + color: #ffffff; + font-style: italic; } + .calendar .calendar-day.calendar-other-month { + color: rgba(255, 255, 255, 0.5); + font-weight: normal; + color: #ffffff; + font-style: italic; } + .calendar .calendar-day.calendar-other-month.calendar-weekend { + color: rgba(255, 255, 255, 0.5); + color: #ffffff; } + .calendar .calendar-day.calendar-today { - color: #ffffff !important; } ++ color: -st-accent-fg-color !important; } + .calendar .calendar-day.calendar-today.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg") !important; } + .calendar .calendar-day.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg"); + background-size: contain; } + .calendar .calendar-day-heading { + font-weight: bold; + text-align: center; + margin: 4px; + padding: 3px 6px; + border-radius: 8px; } + .calendar .calendar-week-number { + font-weight: bold; + font-feature-settings: "tnum"; + text-align: center; + margin: 6px; + padding: 0 6px; + border-radius: 4px; + background-color: rgba(255, 255, 255, 0.2); + color: #ffffff; } + +.events-button .events-box .events-title { + color: #ffffff; + padding-bottom: 6px; } + +.events-button .events-box .events-list { + spacing: 6px; } + .events-button .events-box .events-list .event-box { + spacing: 6px; + border-radius: 8px; } + .events-button .events-box .events-list .event-box .event-time { + color: #ffffff; } + .events-button .events-box .events-list .event-placeholder { + color: #ffffff; + font-style: italic; } + +.world-clocks-button .world-clocks-header { + color: #ffffff; } + .world-clocks-button .world-clocks-header.no-world-clocks { + color: #ffffff; } + +.world-clocks-button .world-clocks-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .world-clocks-button .world-clocks-grid .world-clocks-time { + font-weight: bold; } + .world-clocks-button .world-clocks-grid .world-clocks-time:ltr { + text-align: right; } + .world-clocks-button .world-clocks-grid .world-clocks-time:rtl { + text-align: left; } + .world-clocks-button .world-clocks-grid .world-clocks-timezone { + color: #ffffff; } + +.weather-button .weather-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box .weather-header { + color: #ffffff; } + .weather-button .weather-box .weather-header-box .weather-header.no-location { + color: #ffffff; } + .weather-button .weather-box .weather-header-box .weather-header.location { + font-weight: normal; } + .weather-button .weather-box .weather-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .weather-button .weather-box .weather-grid .weather-forecast-time { + padding-top: 6px; + padding-bottom: 6px; } + .weather-button .weather-box .weather-grid .weather-forecast-icon { + icon-size: 2.182em; + margin-bottom: 4px; } + .weather-button .weather-box .weather-grid .weather-forecast-temp { + font-weight: bold; } + +/* Message List */ +.message-list { + width: 29em; + border: solid rgba(255, 255, 255, 0.5); } + .message-list:ltr { + margin-left: 0; + margin-right: 4px; + padding-right: 6px; + border-right-width: 1px; } + .message-list:rtl { + margin-right: 0; + margin-left: 4px; + padding-left: 6px; + border-left-width: 1px; } + .message-list .message-list-placeholder { + color: rgba(255, 255, 255, 0.25); + color: rgba(255, 255, 255, 0.5); } + .message-list .message-list-placeholder > StIcon { + icon-size: 96px; + margin-bottom: 12px; + -st-icon-style: symbolic; } + +.message-list-sections { + spacing: 12px; } + .message-list-sections:ltr { + margin-right: 12px; } + .message-list-sections:rtl { + margin-left: 12px; } + +.message-list-section, +.message-list-section-list { + spacing: 12px; } + +.message-list-controls { + padding: 12px; + padding-bottom: 6px; + spacing: 6px; } + .message-list-controls .dnd-button { + border-width: 2px; + border-color: transparent; + border-radius: 32px; + border-style: solid; } + .message-list-controls .dnd-button:focus { - border-color: rgba(53, 132, 228, 0.6); } ++ border-color: st-transparentize(-st-accent-color, 0.4); } + +.message { - padding: 0; ++ padding: 6px; + margin: 0; + border-radius: 16px; } - .message:ltr { - padding-right: -2px; } - .message:rtl { - padding-left: -2px; } + .message .message-header { - padding: 0 0.409em; - margin: 6px; - margin-bottom: 0; + spacing: 6px; - color: #ffffff; } ++ color: #ffffff; ++ padding: 0 6px; } ++ .message .message-header:ltr { ++ padding-right: 4px; } ++ .message .message-header:rtl { ++ padding-left: 4px; } + .message .message-header .message-source-icon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + .message .message-header .message-header-content { + spacing: 6px; + min-height: 1.637em; + padding-bottom: 6px; } + .message .message-header .message-header-content .message-source-title { + font-weight: bold; } + .message .message-header .message-header-content .event-time { + color: #ffffff; + padding-bottom: 0.068em; } + .message .message-header .message-header-content .event-time:ltr { + text-align: right; } + .message .message-header .message-header-content .event-time:rtl { + text-align: left; } + .message .message-header .message-expand-button, + .message .message-header .message-close-button { ++ border-radius: 999px; + color: #ffffff; - background-color: rgba(255, 255, 255, 0.1); + padding: 4px; } - .message .message-header .message-expand-button:hover, - .message .message-header .message-close-button:hover { - background-color: rgba(255, 255, 255, 0.19); } - .message .message-header .message-expand-button:active, .message .message-header .message-expand-button:active:hover, - .message .message-header .message-close-button:active, - .message .message-header .message-close-button:active:hover { - background-color: rgba(255, 255, 255, 0.24); } - .message .message-header .message-expand-button:insensitive, - .message .message-header .message-close-button:insensitive { - background-color: rgba(255, 255, 255, 0.07); } + .message .message-header .message-expand-button { + padding: 6px; } + .message .message-header .message-expand-button:ltr { + margin-right: 6px; } + .message .message-header .message-expand-button:rtl { + margin-left: 6px; } + .message .message-box { + padding: 6px; - margin: 6px; + margin-top: 0; + spacing: 6px; } + .message .message-box .message-icon { + icon-size: 48px; } + .message .message-box .message-icon:ltr { + margin-right: 6px; } + .message .message-box .message-icon:rtl { + margin-left: 6px; } + .message .message-box .message-icon.message-themed-icon { + border-radius: 999px; + background-color: rgba(255, 255, 255, 0.07); + icon-size: 1.091em; + min-width: 48px; + min-height: 48px; } + .message .message-box:first-child { + margin-top: 12px; } + .message .message-box .message-content { + spacing: 4px; } + .message .message-box .message-content .message-title { + font-weight: bold; } ++ .message .message-action-bin { ++ padding: 4px; ++ spacing: 6px; } ++ .message .message-action-bin * { ++ margin: 0 4px; } ++ .message .message-action-bin *:first-child:ltr { ++ margin-left: 0; } ++ .message .message-action-bin *:first-child:rtl { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:ltr { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:rtl { ++ margin-left: 0; } + +.url-highlighter { - link-color: #62a0ea; } ++ link-color: st-lighten(-st-accent-color, 20%); } + +/* Media Controls */ +.message-media-control { + padding: 0 18px; + border-radius: 8px; + color: #ffffff; + border: 1px solid transparent; + border-color: rgba(255, 255, 255, 0.4); + margin: 12px 2px; } + .message-media-control:hover { + background-color: #595959; + color: #ffffff; } + .message-media-control:active { + background-color: #5e5e5e; + color: #ffffff; } + .message-media-control:insensitive { + color: white; + border-color: transparent; } + .message-media-control StIcon { + icon-size: 16px; } + +.media-message .message-icon { + border-radius: 8px !important; } + .media-message .message-icon.message-themed-icon { + icon-size: 32px !important; } + +.candidate-popup-content { + padding: 6px; + spacing: 6px; } + +.candidate-index { + padding: 0; + padding-right: 6px; + color: #ffffff; } + +.candidate-box { + padding: 6px 12px 6px 12px; + border-radius: 8px; } + .candidate-box:selected { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + .candidate-box:hover { + background-color: #4d4d4d; + color: white; } + +.candidate-page-button-box { + height: 2em; } + .vertical .candidate-page-button-box { + padding-top: 12px; } + .horizontal .candidate-page-button-box { + padding-left: 12px; } + +.candidate-page-button { + padding: 6px; } + .candidate-page-button StIcon { + icon-size: 16px; } + +.candidate-page-button-previous { + border-radius: 8px 0px 0px 8px; + border-right-width: 0; + box-shadow: none; } + +.candidate-page-button-next { + border-radius: 0px 8px 8px 0px; + box-shadow: none; } + +/* Notifications & Message Tray */ +.notification-banner { + min-height: 64px; + width: 34em; + box-shadow: 0 2px 4px 2px transparent; + border-radius: 16px; + margin: 4px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + +.notification-buttons-bin { + spacing: 0; } + +/* Modal Dialogs */ +.modal-dialog { + background-color: #1a1a1a; - border-radius: 16px; - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); } ++ border-radius: 18px; ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); ++ padding: 24px; } + .modal-dialog .modal-dialog-content-box { - margin: 32px 40px; + spacing: 32px; ++ margin-top: 8px; ++ margin-bottom: 16px; + max-width: 28em; } + +/* End Session Dialog */ +.end-session-dialog { - width: 30em; } ++ width: 24em; } + .end-session-dialog .end-session-dialog-battery-warning, + .end-session-dialog .dialog-list-title { + color: #f6d32d; } + +/* Message Dialog */ +.message-dialog-content { + spacing: 18px; } + .message-dialog-content .message-dialog-title { + text-align: center; } + .message-dialog-content .message-dialog-description { + text-align: center; } + +/* Dialog List */ +.dialog-list { + spacing: 18px; } + .dialog-list .dialog-list-title { + text-align: center; } + .dialog-list .dialog-list-scrollview { + max-height: 200px; } + .dialog-list .dialog-list-box { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-title { + font-weight: bold; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description { + color: #f2f2f2; } + +/* Run Dialog */ +.run-dialog .modal-dialog-content-box { + margin-top: 24px; + margin-bottom: 12px; } + +.run-dialog .run-dialog-entry { + width: 20em; } + +.run-dialog .run-dialog-description { + text-align: center; + color: #cccccc; } + +/* Password or Authentication Dialog */ +.prompt-dialog { + width: 28em; } + .prompt-dialog .modal-dialog-content-box { + margin-bottom: 24px; } + +.prompt-dialog-password-grid { + spacing-rows: 8px; + spacing-columns: 4px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry { + width: auto; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:ltr { + margin-left: 20px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:rtl { + margin-right: 20px; } + +.prompt-dialog-password-layout { + spacing: 8px; } + +.prompt-dialog-password-entry { + width: 20em; } + +.prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label { + text-align: center; } + +.prompt-dialog-error-label { + color: #f6d32d; } + +/* Polkit Dialog */ +.polkit-dialog-user-layout { + text-align: center; + spacing: 8px; + margin-bottom: 6px; } + .polkit-dialog-user-layout .polkit-dialog-user-root-label { + color: #f6d32d; } + +/* Audio selection dialog */ +.audio-device-selection-dialog .modal-dialog-content-box { + margin-bottom: 28px; } + +.audio-device-selection-dialog .audio-selection-box { + spacing: 20px; } + +.audio-selection-device { + border-radius: 16px; } + .audio-selection-device:hover, .audio-selection-device:focus { + background-color: #4d4d4d; } + .audio-selection-device:active { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.audio-selection-device-box { + padding: 20px; + spacing: 20px; } + +.audio-selection-device-icon { + icon-size: 64px; } + +/* Welcome dialog */ +.welcome-dialog-image { + background-image: url("resource:///org/gnome/shell/theme/gnome-shell-start.svg"); + background-size: contain; + /* Reasonable maximum dimensions */ + height: 300px; + width: 300px; } + +/* Access portal dialog */ +.access-dialog { + text-align: center; } + +/* OSD */ +.osd-window { + text-align: center; + font-weight: bold; + spacing: 12px; + padding: 12px 18px; + margin-bottom: 4em; } + .osd-window > * { + spacing: 8px; } + .osd-window StIcon { + icon-size: 32px; } + .osd-window StLabel:ltr { + margin-right: 6px; } + .osd-window StLabel:rtl { + margin-left: 6px; } + .osd-window .level { + margin-bottom: 4px; + min-width: 160px; + -barlevel-height: 6px; + -barlevel-background-color: rgba(255, 255, 255, 0.1); + -barlevel-active-background-color: #ffffff; + -barlevel-overdrive-color: #c01c28; + -barlevel-overdrive-separator-width: 3px; } + .osd-window .level:first-child { + margin-bottom: 0; } + .osd-window .level:ltr { + margin-right: 6px; } + .osd-window .level:rtl { + margin-left: 6px; } + +.osd-monitor-label { - background-color: #3584e4; - color: #ffffff; ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; + border-radius: 16px; + font-size: 3em; + font-weight: bold; + font-feature-settings: "tnum"; + margin: 12px; + padding: 12px; + text-align: center; + min-width: 1.5em; } + +/* Pad OSD */ +.pad-osd-window { + padding: 32px; + background-color: rgba(0, 0, 0, 0.8); } + .pad-osd-window .pad-osd-title-box { + spacing: 12px; } + .pad-osd-window .pad-osd-title-menu-box { + spacing: 6px; } + +.combo-box-label { + width: 15em; } + +/* App Switcher */ +.switcher-popup { + padding: 0; + spacing: 24px; } + +.switcher-list { + padding: 12px; + border-radius: 28px; + box-shadow: 0 8px 8px 0 transparent; } + .switcher-list .switcher-list-item-container { + spacing: 12px; } + .switcher-list .item-box { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .switcher-list .item-box:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(14, 36, 61, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(0, 0, 0, 0.25), 5%); } + .switcher-list .item-box:focus:hover { - background-color: #31353a; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 7%), #ffffff, 87%), 5%); } + .switcher-list .item-box:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #313131; } ++ background-color: st-mix(st-lighten(#000000, 7%), #ffffff, 87%); } + .switcher-list .item-box:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } ++ background-color: st-mix(st-lighten(#000000, 9%), #ffffff, 87%); } + .switcher-list .item-box:active:hover { - background-color: #292929; } ++ background-color: st-lighten(st-lighten(#000000, 9%), 7%); } + .switcher-list .item-box:active:focus { - background-color: #35393e; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 9%), #ffffff, 87%), 5%); } + .switcher-list .item-box:highlighted, .switcher-list .item-box:selected, .switcher-list .item-box:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #333333; } ++ background-color: st-mix(st-lighten(#000000, 8%), #ffffff, 87%); } + .switcher-list .item-box:highlighted:hover, .switcher-list .item-box:selected:hover, .switcher-list .item-box:checked:hover { - background-color: #262626; } ++ background-color: st-lighten(st-lighten(#000000, 8%), 7%); } + .switcher-list .item-box:highlighted:active, .switcher-list .item-box:selected:active, .switcher-list .item-box:checked:active { - background-color: #2b2b2b; } ++ background-color: st-lighten(st-lighten(#000000, 8%), 9%); } + .switcher-list .item-box:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .switcher-list .item-box:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .switcher-list .item-box:hover { + background: none; } + .switcher-list .item-box:selected { + background-color: rgba(255, 255, 255, 0.2); } + .switcher-list .item-box:selected { + background-color: rgba(255, 255, 255, 0.3); } + .switcher-list .separator { + width: 1px; + background: rgba(255, 255, 255, 0.5); } + .switcher-list .thumbnail-box { + padding: 2px; + spacing: 6px; } + .switcher-list .thumbnail { + width: 256px; + border-radius: 8px; } + +.switcher-arrow { + border-color: rgba(255, 255, 255, 0.8); + color: rgba(255, 255, 255, 0.8); } + .switcher-arrow:highlighted { + border-color: #ffffff; + color: #ffffff; } + +.input-source-switcher-symbol { + font-size: 34pt; + width: 96px; + height: 96px; } + +.cycler-highlight { - border: 5px solid #3584e4; } ++ border: 5px solid -st-accent-color; } + +/* Workspace Switcher */ +.workspace-switcher { + margin-bottom: 4em; + spacing: 12px; + padding: 12px 18px; } + +.ws-switcher-indicator { + background-color: rgba(255, 255, 255, 0.5); + padding: 2.6666666667px; + margin: 13.3333333333px; + border-radius: 32px; } + .ws-switcher-indicator:active { + background-color: #ffffff; + padding: 5.3333333333px; + margin: 10.6666666667px; } + +.screenshot-ui-panel { + border-radius: 32px; + padding: 18px; + padding-bottom: 12px; + margin-bottom: 4em; + spacing: 12px; } + +.screenshot-ui-close-button { + padding: 6px !important; + margin-top: 12px; + box-shadow: 0 2px 4px 0 transparent; } + .screenshot-ui-close-button.left { + margin-left: 12px; } + .screenshot-ui-close-button.right { + margin-right: 12px; } + +.screenshot-ui-type-button { + min-width: 48px; + padding: 12px 18px; + border-radius: 14px; } + .screenshot-ui-type-button .icon-label-button-container { + spacing: 0.409em; } + .screenshot-ui-type-button .icon-label-button-container > StIcon { + icon-size: 32px; } + +.screenshot-ui-capture-button { + width: 32px; + height: 32px; + border-radius: 999px; + border: 4px #ffffff; + padding: 4px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle { + background-color: #ffffff; + transition-duration: 200ms; + border-radius: 999px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:hover, .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:focus { + background-color: #4d4d4d; } + .screenshot-ui-capture-button:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:focus .screenshot-ui-capture-button-circle { + background-color: #cccccc; } + .screenshot-ui-capture-button:active .screenshot-ui-capture-button-circle { + background-color: gray; } + .screenshot-ui-capture-button:cast .screenshot-ui-capture-button-circle { + background-color: #c01c28; } + .screenshot-ui-capture-button:cast:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:cast:focus .screenshot-ui-capture-button-circle { + background-color: #d61f2d; } + .screenshot-ui-capture-button:cast:active .screenshot-ui-capture-button-circle { + background-color: #a11722; } + +.screenshot-ui-shot-cast-container { + background-color: rgba(255, 255, 255, 0.1); + border-radius: 999px; + padding: 3px; + spacing: 3px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + +.screenshot-ui-shot-cast-button { + padding: 6px 12px; + background-color: transparent; + border-radius: 999px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + .screenshot-ui-shot-cast-button > StIcon { + icon-size: 16px; } + .screenshot-ui-shot-cast-button:hover, .screenshot-ui-shot-cast-button:focus { + background-color: rgba(255, 255, 255, 0.2); } + .screenshot-ui-shot-cast-button:active { + background-color: rgba(255, 255, 255, 0.5); } + .screenshot-ui-shot-cast-button:checked { + background-color: #ffffff; + color: #000000; } + .screenshot-ui-shot-cast-button:insensitive { + color: rgba(255, 255, 255, 0.5); } + +.screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.3); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.5); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-selection { + border: 2px white; } + +.screenshot-ui-area-selector-handle { + border-radius: 999px; + background-color: white; + box-shadow: 0 1px 3px 2px transparent; + width: 24px; + height: 24px; } + +.screenshot-ui-window-selector { + background-color: #000000; } + .screenshot-ui-window-selector .screenshot-ui-window-selector-window-container { + margin: 100px; } + .screenshot-ui-window-selector:primary-monitor .screenshot-ui-window-selector-window-container { + margin-bottom: 200px; } + +.screenshot-ui-window-selector-window-border { + transition-duration: 200ms; + border-radius: 16px; + border: 6px transparent; } + +.screenshot-ui-window-selector-check { + transition-duration: 200ms; + color: transparent; + border-radius: 999px; + border-width: 12px; + icon-size: 24px; } + +.screenshot-ui-window-selector-window:hover .screenshot-ui-window-selector-window-border { - border-color: #185fb4; } ++ border-color: st-darken(-st-accent-color, 15%); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-window-border { - border-color: #3584e4; - background-color: rgba(53, 132, 228, 0.2); } ++ border-color: -st-accent-color; ++ background-color: st-transparentize(-st-accent-color, 0.8); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-check { - color: #ffffff; - background-color: #3584e4; } ++ color: -st-accent-fg-color; ++ background-color: -st-accent-color; } + +.screenshot-ui-screen-selector { + transition-duration: 200ms; + background-color: rgba(0, 0, 0, 0.5); } + .screenshot-ui-screen-selector:hover { + background-color: rgba(0, 0, 0, 0.3); } + .screenshot-ui-screen-selector:active { + background-color: rgba(0, 0, 0, 0.7); } + .screenshot-ui-screen-selector:checked { + background-color: transparent; + border: 2px white; } + +.screenshot-ui-tooltip { + text-align: center; + -y-offset: 24px; } + +/* Top Bar */ +#panel { + background-color: #000000; + font-weight: bold; + height: 2.2em; + transition-duration: 250ms; } + #panel .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 6px; } + #panel .panel-button:focus, #panel .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button:active, #panel .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button:active:hover, #panel .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button .system-status-icon { + icon-size: 1.091em; + padding: 0 6px; + margin: 0 4px; } + #panel .panel-button .app-menu-icon { + -st-icon-style: symbolic; } + #panel .panel-button .panel-status-menu-box, + #panel .panel-button .panel-status-indicators-box { + spacing: 4px; } + #panel .panel-button .panel-status-menu-box > .system-status-icon, + #panel .panel-button .panel-status-indicators-box > .system-status-icon { + padding: 0; } + #panel .panel-button#panelActivities StBoxLayout { + padding: 0 0.2045em; + spacing: 5px; } + #panel .panel-button#panelActivities .workspace-dot { + border-radius: 999px; + min-width: 0.5455em; + min-height: 0.5455em; + background-color: #ffffff; } + #panel .panel-button.screen-recording-indicator StBoxLayout, #panel .panel-button.screen-sharing-indicator StBoxLayout { + spacing: 0.409em; } + #panel .panel-button.screen-recording-indicator StIcon, #panel .panel-button.screen-sharing-indicator StIcon { + icon-size: 1.091em; } + #panel .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel .panel-button.screen-recording-indicator:focus, #panel .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #d61f2d; } + #panel .panel-button.screen-recording-indicator:active, #panel .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #e02a37; } + #panel .panel-button.screen-recording-indicator:active:hover, #panel .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #e13340; } + #panel .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #ff7800; } + #panel .panel-button.screen-sharing-indicator:focus, #panel .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #ff861a; } + #panel .panel-button.screen-sharing-indicator:active, #panel .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #ff902e; } + #panel .panel-button.screen-sharing-indicator:active:hover, #panel .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ff9638; } + #panel .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel .panel-button.clock-display:focus, #panel .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button.clock-display:active, #panel .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button.clock-display:active:hover, #panel .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel .panel-button.clock-display:active .clock:hover, #panel .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-button.clock-display .messages-indicator { + icon-size: 1.091em; } + #panel:overview, #panel.unlock-screen, #panel.login-screen { + background-color: transparent; } + #panel:overview .panel-button.screen-recording-indicator, #panel.unlock-screen .panel-button.screen-recording-indicator, #panel.login-screen .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel:overview .panel-button.screen-recording-indicator:focus, #panel:overview .panel-button.screen-recording-indicator:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:focus, #panel.unlock-screen .panel-button.screen-recording-indicator:hover, #panel.login-screen .panel-button.screen-recording-indicator:focus, #panel.login-screen .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #d61f2d; } + #panel:overview .panel-button.screen-recording-indicator:active, #panel:overview .panel-button.screen-recording-indicator:checked, #panel.unlock-screen .panel-button.screen-recording-indicator:active, #panel.unlock-screen .panel-button.screen-recording-indicator:checked, #panel.login-screen .panel-button.screen-recording-indicator:active, #panel.login-screen .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #e02a37; } + #panel:overview .panel-button.screen-recording-indicator:active:hover, #panel:overview .panel-button.screen-recording-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:active:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:checked:hover, #panel.login-screen .panel-button.screen-recording-indicator:active:hover, #panel.login-screen .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #e13340; } + #panel:overview .panel-button.screen-sharing-indicator, #panel.unlock-screen .panel-button.screen-sharing-indicator, #panel.login-screen .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #ff7800; } + #panel:overview .panel-button.screen-sharing-indicator:focus, #panel:overview .panel-button.screen-sharing-indicator:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:focus, #panel.unlock-screen .panel-button.screen-sharing-indicator:hover, #panel.login-screen .panel-button.screen-sharing-indicator:focus, #panel.login-screen .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #ff861a; } + #panel:overview .panel-button.screen-sharing-indicator:active, #panel:overview .panel-button.screen-sharing-indicator:checked, #panel.unlock-screen .panel-button.screen-sharing-indicator:active, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked, #panel.login-screen .panel-button.screen-sharing-indicator:active, #panel.login-screen .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #ff902e; } + #panel:overview .panel-button.screen-sharing-indicator:active:hover, #panel:overview .panel-button.screen-sharing-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:active:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked:hover, #panel.login-screen .panel-button.screen-sharing-indicator:active:hover, #panel.login-screen .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ff9638; } + #panel.unlock-screen .panel-button, #panel.login-screen .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; } + #panel.unlock-screen .panel-button:focus, #panel.unlock-screen .panel-button:hover, #panel.login-screen .panel-button:focus, #panel.login-screen .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button:active, #panel.unlock-screen .panel-button:checked, #panel.login-screen .panel-button:active, #panel.login-screen .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button:active:hover, #panel.unlock-screen .panel-button:checked:hover, #panel.login-screen .panel-button:active:hover, #panel.login-screen .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display, #panel.login-screen .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel.unlock-screen .panel-button.clock-display:focus, #panel.unlock-screen .panel-button.clock-display:hover, #panel.login-screen .panel-button.clock-display:focus, #panel.login-screen .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active, #panel.unlock-screen .panel-button.clock-display:checked, #panel.login-screen .panel-button.clock-display:active, #panel.login-screen .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active:hover, #panel.unlock-screen .panel-button.clock-display:checked:hover, #panel.login-screen .panel-button.clock-display:active:hover, #panel.login-screen .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display .clock, #panel.login-screen .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel.unlock-screen .panel-button.clock-display:focus .clock, #panel.unlock-screen .panel-button.clock-display:hover .clock, #panel.login-screen .panel-button.clock-display:focus .clock, #panel.login-screen .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active .clock, #panel.unlock-screen .panel-button.clock-display:checked .clock, #panel.login-screen .panel-button.clock-display:active .clock, #panel.login-screen .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active .clock:hover, #panel.unlock-screen .panel-button.clock-display:checked .clock:hover, #panel.login-screen .panel-button.clock-display:active .clock:hover, #panel.login-screen .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel:overview .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; } + #panel:overview .panel-button:focus, #panel:overview .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel:overview .panel-button:active, #panel:overview .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel:overview .panel-button:active:hover, #panel:overview .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel:overview .panel-button#panelActivities .workspace-dot { + background-color: #ffffff; } + #panel:overview .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel:overview .panel-button.clock-display:focus, #panel:overview .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel:overview .panel-button.clock-display:active, #panel:overview .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel:overview .panel-button.clock-display:active:hover, #panel:overview .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel:overview .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel:overview .panel-button.clock-display:focus .clock, #panel:overview .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel:overview .panel-button.clock-display:active .clock, #panel:overview .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel:overview .panel-button.clock-display:active .clock:hover, #panel:overview .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel .panel-status-indicators-box, + #panel .panel-status-menu-box { + spacing: 2px; } + #panel .power-status.panel-status-indicators-box { + spacing: 0; } + #panel .privacy-indicator { + color: #ff7800; } + +#appMenu { + spacing: 0.409em; } + #appMenu .label-shadow { + color: transparent; } + +#appMenu .panel-status-menu-box { + padding: 0 0.409em; + spacing: 0.409em; } + +.clock-display-box { + spacing: 2px; } + .clock-display-box .clock { + padding-left: 0.818em; + padding-right: 0.818em; } + +/* Activities Ripple */ +.ripple-box { + background-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 0 2px 2px rgba(255, 255, 255, 0.2); + width: 52px; + height: 52px; + border-radius: 0 0 52px 0; } + .ripple-box:rtl { + border-radius: 0 0 0 52px; } + +.quick-settings { + padding: 18px; + border-radius: 36px; } + .quick-settings .icon-button, .quick-settings .login-dialog-button.cancel-button, .quick-settings .login-dialog-button.switch-user-button, .quick-settings .login-dialog-button.login-dialog-session-list-button, .quick-settings .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-settings .pager-button, .quick-settings .message .message-header .message-expand-button, .message .message-header .quick-settings .message-expand-button, + .quick-settings .message .message-header .message-close-button, + .message .message-header .quick-settings .message-close-button, .quick-settings .screenshot-ui-show-pointer-button, .quick-settings .button { + padding: 10.5px; } + +.quick-settings-grid { + spacing-rows: 12px; + spacing-columns: 12px; } + +.quick-toggle, .quick-menu-toggle { + border-radius: 999px; + min-width: 12em; + max-width: 12em; + min-height: 3.273em; + border: none; } + +.quick-toggle { + background-color: none; + /* Move padding into the box; this is to allow menu arrows + to extend to the border */ } + .quick-toggle > StBoxLayout { + spacing: 9px; } + .quick-toggle.button { + padding: 0; } + .quick-toggle > StBoxLayout { + padding: 0 12px; } + .quick-toggle:ltr > StBoxLayout { + padding-left: 15px; } + .quick-toggle:rtl > StBoxLayout { + padding-right: 15px; } + .quick-toggle .quick-toggle-title { + font-weight: bold; } + .quick-toggle StBoxLayout > .quick-toggle-subtitle { + font-weight: normal; } + .quick-toggle .quick-toggle-icon { + icon-size: 1.091em; } + +.quick-menu-toggle .quick-toggle { + min-width: auto; + max-width: auto; } + .quick-menu-toggle .quick-toggle:ltr { + border-radius: 999px 0 0 999px; } + .quick-menu-toggle .quick-toggle:ltr > StBoxLayout { + padding-right: 0.6135em; } + .quick-menu-toggle .quick-toggle:rtl { + border-radius: 0 999px 999px 0; } + .quick-menu-toggle .quick-toggle:rtr > StBoxLayout { + padding-left: 0.6135em; } + .quick-menu-toggle .quick-toggle:ltr:last-child { + border-radius: 999px; } + .quick-menu-toggle .quick-toggle:rtl:last-child { + border-radius: 999px; } + +.quick-menu-toggle .quick-toggle-arrow { + padding: 0.409em 0.71575em; + border-width: 0; + border-color: rgba(255, 255, 255, 0.25); } + .quick-menu-toggle .quick-toggle-arrow:checked { - border-color: #bcd6f6; } ++ border-color: st-lighten(-st-accent-color, 30%); } + .quick-menu-toggle .quick-toggle-arrow:ltr { + border-radius: 0 999px 999px 0; + border-left-width: 1px; } + .quick-menu-toggle .quick-toggle-arrow:rtl { + border-radius: 999px 0 0 999px; + border-right-width: 1px; } + +.quick-slider > StBoxLayout { + spacing: 6px; } + +.quick-slider .icon-button, .quick-slider .login-dialog-button.cancel-button, .quick-slider .login-dialog-button.switch-user-button, .quick-slider .login-dialog-button.login-dialog-session-list-button, .quick-slider .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-slider .pager-button, .quick-slider .message .message-header .message-expand-button, .message .message-header .quick-slider .message-expand-button, +.quick-slider .message .message-header .message-close-button, +.message .message-header .quick-slider .message-close-button, .quick-slider .screenshot-ui-show-pointer-button { + padding: 6px; } + +.quick-slider .slider-bin { + padding: 6px; + border-radius: 999px; } + .quick-slider .slider-bin:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #484c51; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%), 5%); } + .quick-slider .slider-bin:focus:hover { - background-color: #515559; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%), 5%); } + +.quick-toggle-menu { + border-radius: 24px; + margin: 12px 18px 0; } + .quick-toggle-menu:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } ++ background-color: st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%); } + .quick-toggle-menu .popup-menu-item > StIcon { + -st-icon-style: symbolic; + icon-size: 1.091em; } + .quick-toggle-menu .header { + spacing-rows: 3px; + spacing-columns: 12px; + padding-bottom: 12px; } + .quick-toggle-menu .header .icon { + icon-size: 1.6365em; + border-radius: 999px; + padding: 9px; + background-color: rgba(255, 255, 255, 0.2); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + .quick-toggle-menu .header .icon.active { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + .quick-toggle-menu .header .icon.active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + +.quick-settings-system-item > StBoxLayout { + spacing: 12px; } + +.quick-settings-system-item .power-item { + min-height: 0; + min-width: 0; } + .quick-settings-system-item .power-item:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; ++ background-color: st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%); + background-color: transparent; } + +.nm-network-item .wireless-secure-icon { + icon-size: 0.5455em; } + +.bt-device-item .popup-menu-icon { + -st-icon-style: symbolic; } + +.bt-menu-placeholder.popup-menu-item { + text-align: center; + padding: 2em 4em; } + +.device-subtitle { + color: rgba(255, 255, 255, 0.5); } + +.keyboard-brightness-level { + spacing: 6px; } + +.background-apps-quick-toggle { + min-height: 2.728em; + background-color: transparent; } + .background-apps-quick-toggle StIcon { + icon-size: 1.091em !important; } + +.background-app-item .popup-menu-icon { + icon-size: 32px !important; + -st-icon-style: regular !important; } + +.background-app-item .icon-button, .background-app-item .login-dialog-button.cancel-button, .background-app-item .login-dialog-button.switch-user-button, .background-app-item .login-dialog-button.login-dialog-session-list-button, .background-app-item .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .background-app-item .pager-button, .background-app-item .message .message-header .message-expand-button, .message .message-header .background-app-item .message-expand-button, +.background-app-item .message .message-header .message-close-button, +.message .message-header .background-app-item .message-close-button, .background-app-item .screenshot-ui-show-pointer-button { + padding: 6px; + background-color: rgba(255, 255, 255, 0.13); } + .background-app-item .icon-button:hover, .background-app-item .login-dialog-button.cancel-button:hover, .background-app-item .login-dialog-button.switch-user-button:hover, .background-app-item .login-dialog-button.login-dialog-session-list-button:hover, .background-app-item .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .background-app-item .pager-button:hover, .background-app-item .message .message-header .message-expand-button:hover, .message .message-header .background-app-item .message-expand-button:hover, + .background-app-item .message .message-header .message-close-button:hover, + .message .message-header .background-app-item .message-close-button:hover, .background-app-item .screenshot-ui-show-pointer-button:hover { + background-color: rgba(255, 255, 255, 0.22); } + .background-app-item .icon-button:active, .background-app-item .login-dialog-button.cancel-button:active, .background-app-item .login-dialog-button.switch-user-button:active, .background-app-item .login-dialog-button.login-dialog-session-list-button:active, .background-app-item .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .background-app-item .pager-button:active, .background-app-item .message .message-header .message-expand-button:active, .message .message-header .background-app-item .message-expand-button:active, + .background-app-item .message .message-header .message-close-button:active, + .message .message-header .background-app-item .message-close-button:active, .background-app-item .screenshot-ui-show-pointer-button:active { + background-color: rgba(255, 255, 255, 0.31); } + +.background-app-item .spinner { + padding: 6px; } + +.background-app-item.popup-inactive-menu-item { + color: #ffffff; } + +/* OVERVIEW */ - .controls-manager, .secondary-monitor-workspaces { ++.secondary-monitor-workspaces { + spacing: 12px; } + +#overviewGroup { + background-color: #000000; } + - .overview-controls { - padding-bottom: 32px; } - +/* Window Picker */ +.window-picker { + spacing: 6px; } + +.window-icon { + background-color: #000000; + padding: 12px; + border-radius: 16px; + border: 2px solid rgba(255, 255, 255, 0.4); + margin: 18px; } + +.window-close, .screenshot-ui-close-button { + background-color: rgba(31, 31, 31, 0.98); + color: #ffffff; + border-radius: 999px; + box-shadow: 0 2px 4px 0 transparent; + padding: 3px; + height: 32px; + width: 32px; + transition-duration: 100ms; + border: 2px solid transparent; + border-color: rgba(255, 255, 255, 0.4); } + .window-close StIcon, .screenshot-ui-close-button StIcon { + icon-size: 24px; } + .window-close:hover, .screenshot-ui-close-button:hover { + background-color: rgba(48, 48, 48, 0.98); } + .window-close:active, .screenshot-ui-close-button:active { + background-color: rgba(64, 64, 64, 0.98); } + +.workspace-background { + border-radius: 30px; + background-color: rgba(3, 2, 1, 0); + box-shadow: 0 4px 16px 4px transparent; } + +.search-entry { + border-radius: 999px; + margin-top: 12px; + margin-bottom: 6px; + width: 24em; } + .search-entry .search-entry-icon { + icon-size: 1.091em; + margin-top: 2px; + padding: 0 4px; } + +/* Search */ +#searchResults { + margin: 0 4px; } + +#searchResultsContent { + max-width: 1044px; } + +.search-section { + spacing: 18px; } + .search-section .search-section-separator { + height: 8px; + background-color: transparent; } + +.search-section-content { + background-color: #252525; + color: #ffffff; + border-radius: 24px; + padding: 12px; + margin: 0 12px; + border: 2px solid transparent; + border-color: rgba(255, 255, 255, 0.4); } + +.list-search-result, .search-provider-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; + border-radius: 13.2px; } + .list-search-result:focus, .search-provider-icon:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(41, 63, 88, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(37, 37, 37, 0.25), 5%); } + .list-search-result:focus:hover, .search-provider-icon:focus:hover { - background-color: #505458; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 7%), #ffffff, 87%), 5%); } + .list-search-result:hover, .search-provider-icon:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #515151; } ++ background-color: st-mix(st-lighten(#252525, 7%), #ffffff, 87%); } + .list-search-result:active, .search-provider-icon:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #555555; } ++ background-color: st-mix(st-lighten(#252525, 9%), #ffffff, 87%); } + .list-search-result:active:hover, .search-provider-icon:active:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#252525, 9%), 7%); } + .list-search-result:active:focus, .search-provider-icon:active:focus { - background-color: #53575c; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 9%), #ffffff, 87%), 5%); } + .list-search-result:highlighted, .search-provider-icon:highlighted, .list-search-result:selected, .search-provider-icon:selected, .list-search-result:checked, .search-provider-icon:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #535353; } ++ background-color: st-mix(st-lighten(#252525, 8%), #ffffff, 87%); } + .list-search-result:highlighted:hover, .search-provider-icon:highlighted:hover, .list-search-result:selected:hover, .search-provider-icon:selected:hover, .list-search-result:checked:hover, .search-provider-icon:checked:hover { - background-color: #4b4b4b; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 7%); } + .list-search-result:highlighted:active, .search-provider-icon:highlighted:active, .list-search-result:selected:active, .search-provider-icon:selected:active, .list-search-result:checked:active, .search-provider-icon:checked:active { - background-color: #505050; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 9%); } + .list-search-result:insensitive, .search-provider-icon:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .list-search-result:drop, .search-provider-icon:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.search-statustext { + color: rgba(255, 255, 255, 0.8); } + +.grid-search-results { + spacing: 30px; } + +.search-provider-icon:ltr { + margin-right: 4px; } + +.search-provider-icon:rtl { + margin-left: 4px; } + +.search-provider-icon .list-search-provider-content { + spacing: 12px; } + .search-provider-icon .list-search-provider-content .list-search-provider-details { + width: 120px; + color: #ffffff; } + +.list-search-results { + spacing: 6px; } + +.list-search-result .list-search-result-content { + spacing: 6px; } + +.list-search-result .list-search-result-title { + spacing: 12px; + font-weight: bold; } + +.list-search-result .list-search-result-description { + color: #868686; + color: #ffffff; } + +/* Dash */ +#dash { - margin-top: 12px; } ++ padding-left: 6px; ++ padding-right: 6px; } + #dash .dash-background { + background-color: #252525; + border-radius: 28px; + padding-top: 12px; + padding-bottom: 12px; + padding-left: 10px; + padding-right: 10px; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.4); } + #dash .dash-item-container .placeholder { + background-image: none; + background-size: contain; + height: 32px; } + #dash .dash-item-container .empty-dash-drop-target { + width: 32px; + height: 32px; } + #dash .dash-item-container .show-apps, + #dash .dash-item-container .overview-tile, + #dash .dash-item-container .grid-search-result { + margin: 0 2px; + padding-bottom: 12px; } + #dash .dash-item-container .show-apps .overview-icon, + #dash .dash-item-container .overview-tile .overview-icon, + #dash .dash-item-container .grid-search-result .overview-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + #dash .dash-item-container .show-apps:focus .overview-icon, + #dash .dash-item-container .overview-tile:focus .overview-icon, + #dash .dash-item-container .grid-search-result:focus .overview-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(41, 63, 88, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(37, 37, 37, 0.25), 5%); } + #dash .dash-item-container .show-apps:focus .overview-icon:hover, + #dash .dash-item-container .overview-tile:focus .overview-icon:hover, + #dash .dash-item-container .grid-search-result:focus .overview-icon:hover { - background-color: #505458; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 7%), #ffffff, 87%), 5%); } + #dash .dash-item-container .show-apps:hover .overview-icon, + #dash .dash-item-container .overview-tile:hover .overview-icon, + #dash .dash-item-container .grid-search-result:hover .overview-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #515151; } ++ background-color: st-mix(st-lighten(#252525, 7%), #ffffff, 87%); } + #dash .dash-item-container .show-apps:active .overview-icon, + #dash .dash-item-container .overview-tile:active .overview-icon, + #dash .dash-item-container .grid-search-result:active .overview-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #555555; } ++ background-color: st-mix(st-lighten(#252525, 9%), #ffffff, 87%); } + #dash .dash-item-container .show-apps:active .overview-icon:hover, + #dash .dash-item-container .overview-tile:active .overview-icon:hover, + #dash .dash-item-container .grid-search-result:active .overview-icon:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#252525, 9%), 7%); } + #dash .dash-item-container .show-apps:active .overview-icon:focus, + #dash .dash-item-container .overview-tile:active .overview-icon:focus, + #dash .dash-item-container .grid-search-result:active .overview-icon:focus { - background-color: #53575c; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 9%), #ffffff, 87%), 5%); } + #dash .dash-item-container .show-apps:checked .overview-icon, + #dash .dash-item-container .overview-tile:checked .overview-icon, + #dash .dash-item-container .grid-search-result:checked .overview-icon { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #535353; } ++ background-color: st-mix(st-lighten(#252525, 8%), #ffffff, 87%); } + #dash .dash-item-container .show-apps:checked .overview-icon:hover, + #dash .dash-item-container .overview-tile:checked .overview-icon:hover, + #dash .dash-item-container .grid-search-result:checked .overview-icon:hover { - background-color: #4b4b4b; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 7%); } + #dash .dash-item-container .show-apps:checked .overview-icon:active, + #dash .dash-item-container .overview-tile:checked .overview-icon:active, + #dash .dash-item-container .grid-search-result:checked .overview-icon:active { - background-color: #505050; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 9%); } + #dash .dash-item-container .app-grid-running-dot { + offset-y: -13px; } + #dash .dash-separator { + width: 1px; + margin-left: 4px; + margin-right: 4px; + background-color: rgba(255, 255, 255, 0.1); + width: 2px; + background-color: rgba(255, 255, 255, 0.4); } + #dash .dash-separator, + #dash .dash-background { + margin-bottom: 12px; } + +.dash-label { + -y-offset: 8px; } + +/* App Grid */ +.icon-grid { + row-spacing: 12px; + column-spacing: 12px; + max-row-spacing: 36px; + max-column-spacing: 36px; + page-padding-top: 24px; + page-padding-bottom: 24px; + page-padding-left: 18px; + page-padding-right: 18px; } + +/* App Icons */ +.overview-tile, .grid-search-result { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; + border-radius: 24px; + padding: 12px; } + .overview-tile:focus, .grid-search-result:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(14, 36, 61, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(0, 0, 0, 0.25), 5%); } + .overview-tile:focus:hover, .grid-search-result:focus:hover { - background-color: #31353a; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 7%), #ffffff, 87%), 5%); } + .overview-tile:hover, .grid-search-result:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #313131; } ++ background-color: st-mix(st-lighten(#000000, 7%), #ffffff, 87%); } + .overview-tile:active, .grid-search-result:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } ++ background-color: st-mix(st-lighten(#000000, 9%), #ffffff, 87%); } + .overview-tile:active:hover, .grid-search-result:active:hover { - background-color: #292929; } ++ background-color: st-lighten(st-lighten(#000000, 9%), 7%); } + .overview-tile:active:focus, .grid-search-result:active:focus { - background-color: #35393e; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 9%), #ffffff, 87%), 5%); } + .overview-tile:highlighted, .grid-search-result:highlighted, .overview-tile:selected, .grid-search-result:selected, .overview-tile:checked, .grid-search-result:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #333333; } ++ background-color: st-mix(st-lighten(#000000, 8%), #ffffff, 87%); } + .overview-tile:highlighted:hover, .grid-search-result:highlighted:hover, .overview-tile:selected:hover, .grid-search-result:selected:hover, .overview-tile:checked:hover, .grid-search-result:checked:hover { - background-color: #262626; } ++ background-color: st-lighten(st-lighten(#000000, 8%), 7%); } + .overview-tile:highlighted:active, .grid-search-result:highlighted:active, .overview-tile:selected:active, .grid-search-result:selected:active, .overview-tile:checked:active, .grid-search-result:checked:active { - background-color: #2b2b2b; } ++ background-color: st-lighten(st-lighten(#000000, 8%), 9%); } + .overview-tile:insensitive, .grid-search-result:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .overview-tile:drop, .grid-search-result:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .overview-tile .overview-icon.overview-icon-with-label > StBoxLayout, .grid-search-result .overview-icon.overview-icon-with-label > StBoxLayout { + spacing: 6px; } + +.app-folder { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } ++ background-color: st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%); } + .app-folder:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #35393e; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%), 5%); } + .app-folder:focus:hover { - background-color: #3e4246; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%), 5%); } + .app-folder:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #3e3e3e; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%); } + .app-folder:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%); } + .app-folder:active:hover { - background-color: #383838; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), 4%); } + .app-folder:active:focus { - background-color: #484c51; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%), 5%); } + .app-folder:highlighted, .app-folder:selected, .app-folder:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #474747; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), #ffffff, 87%); } + .app-folder:highlighted:hover, .app-folder:selected:hover, .app-folder:checked:hover { - background-color: #363636; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), 4%); } + .app-folder:highlighted:active, .app-folder:selected:active, .app-folder:checked:active { - background-color: #424242; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 8%), 9%); } + .app-folder:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); - background-color: #0f0f0f; ++ color: st-transparentize(#ffffff, 0.5); ++ background-color: st-darken(st-mix(#ffffff, #000000, 9%), 3%); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .app-folder:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.app-grid-running-dot { + height: 5px; + width: 5px; + border-radius: 5px; + background-color: #ffffff; + offset-y: 6px; } + +.app-folder-dialog-container { + padding-top: 2.2em; } + +.app-folder-dialog { + width: 720px; + height: 720px; + border-radius: 64px; + background-color: #252525; + color: #ffffff; + padding: 0 2px; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.4); } + .app-folder-dialog .folder-name-container { + padding: 24px 36px; + padding-bottom: 0; } + .app-folder-dialog .folder-name-container .folder-name-entry { + width: 12em; } + .app-folder-dialog .icon-button, .app-folder-dialog .login-dialog-button.cancel-button, .app-folder-dialog .login-dialog-button.switch-user-button, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button, .app-folder-dialog .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .app-folder-dialog .pager-button, .app-folder-dialog .message .message-header .message-expand-button, .message .message-header .app-folder-dialog .message-expand-button, + .app-folder-dialog .message .message-header .message-close-button, + .message .message-header .app-folder-dialog .message-close-button, .app-folder-dialog .screenshot-ui-show-pointer-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #535353; } ++ background-color: st-mix(st-mix(#ffffff, #252525, 9%), #ffffff, 87%); } + .app-folder-dialog .icon-button:hover, .app-folder-dialog .login-dialog-button.cancel-button:hover, .app-folder-dialog .login-dialog-button.switch-user-button:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:hover, .app-folder-dialog .message .message-header .message-expand-button:hover, .message .message-header .app-folder-dialog .message-expand-button:hover, + .app-folder-dialog .message .message-header .message-close-button:hover, + .message .message-header .app-folder-dialog .message-close-button:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5c5c5c; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #252525, 9%), 4%), #ffffff, 87%); } + .app-folder-dialog .icon-button:active, .app-folder-dialog .login-dialog-button.cancel-button:active, .app-folder-dialog .login-dialog-button.switch-user-button:active, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active, .app-folder-dialog .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .app-folder-dialog .pager-button:active, .app-folder-dialog .message .message-header .message-expand-button:active, .message .message-header .app-folder-dialog .message-expand-button:active, + .app-folder-dialog .message .message-header .message-close-button:active, + .message .message-header .app-folder-dialog .message-close-button:active, .app-folder-dialog .screenshot-ui-show-pointer-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #676767; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #252525, 9%), 9%), #ffffff, 87%); } + .app-folder-dialog .icon-button:active:hover, .app-folder-dialog .login-dialog-button.cancel-button:active:hover, .app-folder-dialog .login-dialog-button.switch-user-button:active:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:hover, .app-folder-dialog .message .message-header .message-expand-button:active:hover, .message .message-header .app-folder-dialog .message-expand-button:active:hover, + .app-folder-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .app-folder-dialog .message-close-button:active:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:active:hover { - background-color: #5a5a5a; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #252525, 9%), 9%), 4%); } + .app-folder-dialog .icon-button:active:focus, .app-folder-dialog .login-dialog-button.cancel-button:active:focus, .app-folder-dialog .login-dialog-button.switch-user-button:active:focus, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:focus, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:focus, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:focus, .app-folder-dialog .message .message-header .message-expand-button:active:focus, .message .message-header .app-folder-dialog .message-expand-button:active:focus, + .app-folder-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .app-folder-dialog .message-close-button:active:focus, .app-folder-dialog .screenshot-ui-show-pointer-button:active:focus { - background-color: #65686d; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #252525, 9%), 9%), #ffffff, 87%), 5%); } + .app-folder-dialog .page-indicators { + margin-bottom: 24px; } + .app-folder-dialog .page-navigation-arrow { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .app-folder-dialog .page-navigation-arrow:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #515151; } ++ background-color: st-mix(st-lighten(#252525, 7%), #ffffff, 87%); } + .app-folder-dialog .page-navigation-arrow:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #555555; } ++ background-color: st-mix(st-lighten(#252525, 9%), #ffffff, 87%); } + .app-folder-dialog .page-navigation-arrow:active:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#252525, 9%), 7%); } + .app-folder-dialog .page-navigation-arrow:active:focus { - background-color: #53575c; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 9%), #ffffff, 87%), 5%); } + .app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .app-folder-dialog .overview-tile:focus, .app-folder-dialog .grid-search-result:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(41, 63, 88, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(37, 37, 37, 0.25), 5%); } + .app-folder-dialog .overview-tile:focus:hover, .app-folder-dialog .grid-search-result:focus:hover { - background-color: #505458; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 7%), #ffffff, 87%), 5%); } + .app-folder-dialog .overview-tile:hover, .app-folder-dialog .grid-search-result:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #515151; } ++ background-color: st-mix(st-lighten(#252525, 7%), #ffffff, 87%); } + .app-folder-dialog .overview-tile:active, .app-folder-dialog .grid-search-result:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #555555; } ++ background-color: st-mix(st-lighten(#252525, 9%), #ffffff, 87%); } + .app-folder-dialog .overview-tile:active:hover, .app-folder-dialog .grid-search-result:active:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#252525, 9%), 7%); } + .app-folder-dialog .overview-tile:active:focus, .app-folder-dialog .grid-search-result:active:focus { - background-color: #53575c; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#252525, 9%), #ffffff, 87%), 5%); } + .app-folder-dialog .overview-tile:highlighted, .app-folder-dialog .grid-search-result:highlighted, .app-folder-dialog .overview-tile:selected, .app-folder-dialog .grid-search-result:selected, .app-folder-dialog .overview-tile:checked, .app-folder-dialog .grid-search-result:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #535353; } ++ background-color: st-mix(st-lighten(#252525, 8%), #ffffff, 87%); } + .app-folder-dialog .overview-tile:highlighted:hover, .app-folder-dialog .grid-search-result:highlighted:hover, .app-folder-dialog .overview-tile:selected:hover, .app-folder-dialog .grid-search-result:selected:hover, .app-folder-dialog .overview-tile:checked:hover, .app-folder-dialog .grid-search-result:checked:hover { - background-color: #4b4b4b; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 7%); } + .app-folder-dialog .overview-tile:highlighted:active, .app-folder-dialog .grid-search-result:highlighted:active, .app-folder-dialog .overview-tile:selected:active, .app-folder-dialog .grid-search-result:selected:active, .app-folder-dialog .overview-tile:checked:active, .app-folder-dialog .grid-search-result:checked:active { - background-color: #505050; } ++ background-color: st-lighten(st-lighten(#252525, 8%), 9%); } + .app-folder-dialog .overview-tile:insensitive, .app-folder-dialog .grid-search-result:insensitive { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.5); ++ color: st-transparentize(#ffffff, 0.5); + background-color: #252525; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .app-folder-dialog .overview-tile:drop, .app-folder-dialog .grid-search-result:drop { - background-color: rgba(53, 132, 228, 0.2); - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.rename-folder-popup .rename-folder-popup-item { + spacing: 6px; } + .rename-folder-popup .rename-folder-popup-item:ltr, .rename-folder-popup .rename-folder-popup-item:rtl { + padding: 0 12px; } + +.page-indicator { + padding: 6px 12px 0; + transition-duration: 400ms; } + .page-indicator .page-indicator-icon { + width: 10px; + height: 10px; + border-radius: 999px; + background-color: #ffffff; + transition-duration: 400ms; } + +.apps-scroll-view { + padding: 0; } + +.system-action-icon { + background-color: rgba(255, 255, 255, 0.1); + color: #ffffff; + border-radius: 999px; + icon-size: 48px; + box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.4); } + +.page-navigation-hint.dnd { + background: rgba(255, 255, 255, 0.1); } + +.page-navigation-hint.next:ltr, .page-navigation-hint.previous:rtl { + background-gradient-start: rgba(255, 255, 255, 0.05); + background-gradient-end: transparent; + background-gradient-direction: horizontal; + border-radius: 24px 0px 0px 24px; } + +.page-navigation-hint.previous:ltr, .page-navigation-hint.next:rtl { + background-gradient-start: transparent; + background-gradient-end: rgba(255, 255, 255, 0.05); + background-gradient-direction: horizontal; + border-radius: 0px 24px 24px 0px; } + +.page-navigation-arrow { + margin: 6px; + padding: 18px; + width: 24px; + height: 24px; + border-radius: 999px; + transition-duration: 100ms; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; } + .page-navigation-arrow > StIcon { + color: #ffffff; } + .page-navigation-arrow:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #313131; } ++ background-color: st-mix(st-lighten(#000000, 7%), #ffffff, 87%); } + .page-navigation-arrow:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } ++ background-color: st-mix(st-lighten(#000000, 9%), #ffffff, 87%); } + .page-navigation-arrow:active:hover { - background-color: #292929; } ++ background-color: st-lighten(st-lighten(#000000, 9%), 7%); } + .page-navigation-arrow:active:focus { - background-color: #35393e; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 9%), #ffffff, 87%), 5%); } + +/* Workspace pager */ +.workspace-thumbnails { + visible-width: 32px; + spacing: 6px; + padding: 6px; } + .workspace-thumbnails .workspace-thumbnail { + color: #ffffff; + background-color: #262626; + border-radius: 4px; + border: 1px solid transparent; + border-color: rgba(255, 255, 255, 0.4); } + .workspace-thumbnails .placeholder { + background-image: url("resource:///org/gnome/shell/theme/workspace-placeholder.svg"); + background-size: contain; + width: 18px; } + +.workspace-thumbnail-indicator { - border: 3px solid #3584e4; ++ border: 3px solid -st-accent-color; + border-radius: 8px; } + +.ripple-pointer-location { + width: 50px; + height: 50px; + border-radius: 25px; - background-color: rgba(188, 214, 246, 0.3); - box-shadow: 0 0 2px 2px #8fbbf0; } ++ background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 30%); ++ box-shadow: 0 0 2px 2px st-lighten(-st-accent-color, 20%); } + +.pie-timer { + width: 60px; + height: 60px; + -pie-border-width: 3px; - -pie-border-color: #3584e4; - -pie-background-color: rgba(233, 242, 252, 0.3); } ++ -pie-border-color: -st-accent-color; ++ -pie-background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 40%); } + +.magnifier-zoom-region { - border: 2px solid #3584e4; } ++ border: 2px solid -st-accent-color; } + .magnifier-zoom-region.full-screen { + border-width: 0; } + +.select-area-rubberband { - background-color: rgba(53, 132, 228, 0.3); - border: 1px solid #3584e4; } ++ background-color: st-transparentize(-st-accent-color, 0.7); ++ border: 1px solid -st-accent-color; } + +.user-icon { + background-size: contain; + border-radius: 999px; + icon-size: 64px; + background-color: rgba(255, 255, 255, 0.05); + color: #ffffff; } + .user-icon StIcon { + padding: 12px; } + .user-icon.user-avatar { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + +.lightbox { + background-color: black; } + +.flashspot { + background-color: white; } + +.hidden { + color: transparent; } + +.caps-lock-warning-label { + text-align: center; + padding-bottom: 8px; + color: #f6d32d; } + +/* Workspace animation */ +.workspace-animation { + background-color: #0d0d0d; } + +/* Tiled window previews */ +.tile-preview { - background-color: rgba(53, 132, 228, 0.5); - border: 1px solid #3584e4; } ++ background-color: st-transparentize(-st-accent-color, 0.5); ++ border: 1px solid -st-accent-color; } + +/* On-screen Keyboard */ +#keyboard { + background-color: #000000; + box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.2); } + #keyboard .page-indicator { + padding: 6px; } + #keyboard .page-indicator .page-indicator-icon { + width: 8px; + height: 8px; } + +.key-container { + padding: 4px; + spacing: 4px; } + +.keyboard-key { + font-size: 1.455em; + font-weight: bold; + min-height: 1.2em; + min-width: 1.2em; + border-width: 1px; + border-style: solid; + border-radius: 10px; + box-shadow: 0 1px 0 0 transparent; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #727272; } ++ background-color: st-mix(st-mix(#ffffff, #4d4d4d, 9%), #ffffff, 87%); } + .keyboard-key:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #484c51; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%), 5%); } + .keyboard-key:focus:hover { - background-color: #515559; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%), 5%); } + .keyboard-key:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #7b7b7b; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%), #ffffff, 87%); } + .keyboard-key:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #868686; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%); } + .keyboard-key:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .keyboard-key:active:focus { - background-color: #82868b; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%), 5%); } + .keyboard-key:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #848484; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), #ffffff, 87%); } + .keyboard-key:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .keyboard-key:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + .keyboard-key:grayed { + background-color: #121212; + color: #ffffff; + border-color: rgba(255, 255, 255, 0.2); } + .keyboard-key.default-key { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #5d5d5d; ++ background-color: st-mix(st-mix(#ffffff, #333333, 9%), #ffffff, 87%); + border-radius: 10px; } + .keyboard-key.default-key:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #666666; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #333333, 9%), 4%), #ffffff, 87%); } + .keyboard-key.default-key:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #717171; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #333333, 9%), 9%), #ffffff, 87%); } + .keyboard-key.default-key:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 9%), 4%); } + .keyboard-key.default-key:active:focus { - background-color: #6e7277; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #333333, 9%), 9%), #ffffff, 87%), 5%); } + .keyboard-key.default-key:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #6f6f6f; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #333333, 9%), 8%), #ffffff, 87%); } + .keyboard-key.default-key:checked:hover { - background-color: #646464; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 8%), 4%); } + .keyboard-key.default-key:checked:active { - background-color: #707070; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #333333, 9%), 8%), 9%); } + .keyboard-key.default-key:latched { - border-color: #4b92e7; - background-color: #3584e4; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + .keyboard-key.enter-key { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: #ffffff; - background-color: #5f9ee9; ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-mix(-st-accent-fg-color, -st-accent-color, 9%), #ffffff, 87%); + border-radius: 10px; + color: #ffffff; } + .keyboard-key.enter-key:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: #ffffff; - background-color: #6fa7eb; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 4%), #ffffff, 87%); } + .keyboard-key.enter-key:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: #ffffff; - background-color: #82b3ee; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%), #ffffff, 87%); } + .keyboard-key.enter-key:active:hover { - background-color: #81b3ee; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%), 4%); } + .keyboard-key.enter-key:active:focus { - background-color: #7eb1ee; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 9%), #ffffff, 87%), 5%); } + .keyboard-key.enter-key:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); - color: #ffffff; - background-color: #7eb1ed; } ++ color: -st-accent-fg-color; ++ background-color: st-mix(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%), #ffffff, 87%); } + .keyboard-key.enter-key:checked:hover { - background-color: #7db0ed; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%), 4%); } + .keyboard-key.enter-key:checked:active { - background-color: #93bdf0; } ++ background-color: st-lighten(st-lighten(st-mix(-st-accent-fg-color, -st-accent-color, 9%), 8%), 9%); } + .keyboard-key.shift-key-uppercase { + background-color: gray; + color: #000000; } + .keyboard-key.shift-key-uppercase:hover { + background-color: #8c8c8c; + color: #0d0d0d; } + .keyboard-key StIcon { + icon-size: 24px; } + +.keyboard-subkeys { + -arrow-border-radius: 16px; + -arrow-background-color: #000000; + -arrow-border-width: 1px; + -arrow-border-color: #171717; + -arrow-base: 20px; + -arrow-rise: 10px; + -boxpointer-gap: 6px; + padding: 6px; } + .keyboard-subkeys .keyboard-key { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #727272; ++ background-color: st-mix(st-mix(#ffffff, #4d4d4d, 9%), #ffffff, 87%); + border-radius: 10px; } + .keyboard-subkeys .keyboard-key:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #484c51; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%), 5%); } + .keyboard-subkeys .keyboard-key:focus:hover { - background-color: #515559; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%), 5%); } + .keyboard-subkeys .keyboard-key:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #7b7b7b; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%), #ffffff, 87%); } + .keyboard-subkeys .keyboard-key:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #868686; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%); } + .keyboard-subkeys .keyboard-key:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .keyboard-subkeys .keyboard-key:active:focus { - background-color: #82868b; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%), 5%); } + .keyboard-subkeys .keyboard-key:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #848484; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), #ffffff, 87%); } + .keyboard-subkeys .keyboard-key:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .keyboard-subkeys .keyboard-key:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + +.emoji-page .keyboard-key { + background-color: transparent; + border: none; + color: initial; } + +.emoji-panel .keyboard-key:latched { - border-color: #4b92e7; - background-color: #3584e4; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + +.word-suggestions { + spacing: 12px; + min-height: 17pt; + padding: 12px; + color: #ffffff; } + .word-suggestions StButton { + margin: 0 3px; + min-width: 32px; + border-radius: 4px; + padding: 0px 18px; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .word-suggestions StButton:insensitive { + background-color: transparent !important; } + .word-suggestions StButton:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #484c51; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #1a1a1a, 9%), #ffffff, 87%), 5%); } + .word-suggestions StButton:focus:hover { - background-color: #515559; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #1a1a1a, 9%), 4%), #ffffff, 87%), 5%); } + .word-suggestions StButton:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #7b7b7b; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 4%), #ffffff, 87%); } + .word-suggestions StButton:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #868686; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%); } + .word-suggestions StButton:active:hover { - background-color: #7e7e7e; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), 4%); } + .word-suggestions StButton:active:focus { - background-color: #82868b; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 9%), #ffffff, 87%), 5%); } + .word-suggestions StButton:checked { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #848484; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), #ffffff, 87%); } + .word-suggestions StButton:checked:hover { - background-color: #7c7c7c; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 4%); } + .word-suggestions StButton:checked:active { - background-color: #888888; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #4d4d4d, 9%), 8%), 9%); } + +/* Looking Glass */ ++.lg-dialog StEntry { ++ min-height: 1.5em; } ++ ++.lg-dialog .shell-link { ++ color: st-lighten(-st-accent-color, 20%); } ++ .lg-dialog .shell-link:hover { ++ color: st-lighten(st-lighten(-st-accent-color, 20%), 10%); } ++ .lg-dialog .shell-link:active { ++ color: st-darken(st-lighten(-st-accent-color, 20%), 10%); } ++ ++.lg-dialog .actor-link { ++ color: st-darken(#ffffff, 20%); } ++ .lg-dialog .actor-link:hover { ++ color: #ffffff; } ++ .lg-dialog .actor-link:active { ++ color: st-lighten(#ffffff, 20%); } ++ .lg-dialog .actor-link StIcon { ++ icon-size: 12px; } ++ ++.lg-completions-text { ++ font-style: italic; } ++ +#LookingGlassDialog { + background-color: rgba(0, 0, 0, 0.98); + color: #ffffff; + border-radius: 16px; + margin-top: 4px; + border: 2px solid transparent; + padding: 6px; + spacing: 6px; + box-shadow: 0 2px 4px 0 transparent; + border-color: rgba(255, 255, 255, 0.4); + background-color: #000000; + box-shadow: none; } + #LookingGlassDialog > #Toolbar { + border: none; + padding: 6px; + border-radius: 0; + background-color: transparent; + spacing: 6px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button { + padding: 6px 12px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button > StIcon { + icon-size: 16px; } + #LookingGlassDialog .labels { + spacing: 6px; } + #LookingGlassDialog .notebook-tab { ++ background-color: transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 12px; + padding: 6px 12px; } - #LookingGlassDialog StBoxLayout#EvalBox { - padding: 4px; - spacing: 6px; - padding: 6px; } - #LookingGlassDialog StBoxLayout#ResultsArea { - spacing: 6px; - padding: 6px; } - - .lg-dialog StEntry { - min-height: 1.5em; } - - .lg-dialog .shell-link { - color: #62a0ea; } - .lg-dialog .shell-link:hover { - color: #8fbbf0; } - .lg-dialog .shell-link:active { - color: #3585e4; } - - .lg-dialog .actor-link { - color: #ffffff; } - .lg-dialog .actor-link:hover { - color: white; } - .lg-dialog .actor-link:active { - color: #cccccc; } - .lg-dialog .actor-link StIcon { - icon-size: 12px; } - - .lg-completions-text { - font-style: italic; } - - .lg-obj-inspector-title { - spacing: 6px; } ++ #LookingGlassDialog .notebook-tab:selected { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%); } ++ #LookingGlassDialog .notebook-tab:selected:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), 4%); } ++ #LookingGlassDialog .notebook-tab:selected:focus { ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%), 5%); } + - .lg-obj-inspector-button { - border: 1px solid rgba(255, 255, 255, 0.5); - padding: 4px; - border-radius: 8px; } - .lg-obj-inspector-button:hover { - border: 1px solid #ffffff; } ++#LookingGlassPropertyInspector { ++ background-color: #000000; ++ color: #ffffff; ++ border-radius: 16px; ++ border: 1px solid rgba(255, 255, 255, 0.2); ++ padding: 12px; ++ border-color: rgba(255, 255, 255, 0.4); } ++ #LookingGlassPropertyInspector .lg-obj-inspector-title { ++ spacing: 4px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button { ++ padding: 6px 12px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button { ++ margin: 4px; ++ padding: 6px; ++ border-radius: 999px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button > StIcon { ++ icon-size: 16px; } + - #lookingGlassExtensions { ++#LookingGlassEvaluator { + padding: 6px; } ++ #LookingGlassEvaluator .evaluator-results { ++ spacing: 6px; } + - .lg-extensions-list { ++#LookingGlassWindows { + padding: 6px; + spacing: 6px; } ++ #LookingGlassWindows .lg-window { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%); ++ margin: 0; ++ padding: 12px; } + - .lg-extension-meta { ++#LookingGlassExtensions .lg-extensions-list { ++ padding: 6px; + spacing: 6px; } + - #LookingGlassPropertyInspector { - background: #1a1a1a; - border: 1px solid rgba(255, 255, 255, 0.5); - border-radius: 8px; - padding: 6px; } ++#LookingGlassExtensions .lg-extension { ++ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); ++ color: #ffffff; ++ background-color: st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%); ++ margin: 0; ++ spacing: 4px; ++ padding: 12px; } ++ #LookingGlassExtensions .lg-extension .lg-extension-name { ++ color: #ffffff !important; } ++ #LookingGlassExtensions .lg-extension .lg-extension-meta { ++ spacing: 12px; } + - .lg-debug-flag-button { - color: #ffffff; } - .lg-debug-flag-button StLabel { - padding: 6px, 12px; } - .lg-debug-flag-button:hover { - color: white; } - .lg-debug-flag-button:active { - color: #cccccc; } ++#LookingGlassExtensions .lg-extensions-none { ++ color: rgba(255, 255, 255, 0.5); } + - .lg-debug-flags-header { - padding-top: 12px; - padding: 6px; } ++#LookingGlassActors { ++ padding: 6px; ++ spacing: 4px; } ++ ++#LookingGlassDebugFlags .lg-debug-flags-header { ++ padding: 6px; ++ padding-top: 12px; } ++ ++#LookingGlassDebugFlags .lg-debug-flag-button { ++ padding: 9px 12px; ++ margin-bottom: 6px; } ++ #LookingGlassDebugFlags .lg-debug-flag-button StLabel { ++ font-weight: normal !important; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch { ++ background: rgba(255, 255, 255, 0.3); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:hover { ++ background: rgba(255, 255, 255, 0.4); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } + +.login-dialog, +.unlock-dialog { + color: #ffffff; } + .login-dialog .caps-lock-warning-label, + .login-dialog .login-dialog-message-warning, + .unlock-dialog .caps-lock-warning-label, + .unlock-dialog .login-dialog-message-warning { + color: #ffffff; } + .login-dialog .login-dialog-prompt-layout, + .unlock-dialog .login-dialog-prompt-layout { + width: 25em; + spacing: 9px; } + +.login-dialog-button.cancel-button { + padding: 9px; } + +.login-dialog-button-box { + spacing: 12px; } + +.conflicting-session-dialog-content { + spacing: 20px; } + .conflicting-session-dialog-content .conflicting-session-dialog-title { + text-align: center; + margin-bottom: 5px; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc { + text-align: center; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc-warning { + text-align: center; + color: #f6d32d; } + +.login-dialog-logo-bin { + margin: 3em 0; } + +.login-dialog-banner-view { + max-width: 25em; } + .login-dialog-banner-view .login-dialog-banner { + color: #e6e6e6; } + +.login-dialog-message { + text-align: center; } + +.login-dialog-message-hint, .login-dialog-message { + color: #e6e6e6; + min-height: 2.75em; } + +.login-dialog-user-selection-box { + padding-top: 4em; + padding-bottom: 8em; } + +.login-dialog-not-listed-label { + padding: 6px; } + +.login-dialog-not-listed-button { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; + background-color: #000000; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + box-shadow: none; + border: none; + padding: 0 6px; + margin: 6px; } + .login-dialog-not-listed-button:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: rgba(14, 36, 61, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, rgba(0, 0, 0, 0.25), 5%); } + .login-dialog-not-listed-button:focus:hover { - background-color: #31353a; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 7%), #ffffff, 87%), 5%); } + .login-dialog-not-listed-button:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #313131; } ++ background-color: st-mix(st-lighten(#000000, 7%), #ffffff, 87%); } + .login-dialog-not-listed-button:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; } ++ background-color: st-mix(st-lighten(#000000, 9%), #ffffff, 87%); } + .login-dialog-not-listed-button:active:hover { - background-color: #292929; } ++ background-color: st-lighten(st-lighten(#000000, 9%), 7%); } + .login-dialog-not-listed-button:active:focus { - background-color: #35393e; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(#000000, 9%), #ffffff, 87%), 5%); } + +.login-dialog-auth-list-view { + -st-vfade-offset: 3em; } + +.login-dialog-auth-list { + spacing: 6px; + margin-left: 2em; } + +.login-dialog-auth-list-title { + margin-left: 2em; } + +.login-dialog-auth-list-item { + border-radius: 16px; + padding: 4px; + color: #b3b3b3; } + .login-dialog-auth-list-item:focus, .login-dialog-auth-list-item:selected { - background-color: #3584e4; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.login-dialog-auth-list-label:ltr { + padding-left: 15px; + text-align: left; } + +.login-dialog-auth-list-label:rtl { + padding-right: 15px; + text-align: right; } + +.login-dialog-user-list-view { + width: 25em; + -st-vfade-offset: 3em; } + .login-dialog-user-list-view .login-dialog-user-list { + margin: 0 8px; + spacing: 12px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #353535; ++ background-color: st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%); + border-radius: 16px; + padding: 9px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(53, 132, 228, 0.8) !important; - background-color: #35393e; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2) !important; ++ background-color: st-mix(-st-accent-color, st-mix(st-mix(#ffffff, #000000, 9%), #ffffff, 87%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected:hover, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus:hover { - background-color: #3e4246; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:hover { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #3e3e3e; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 4%), #ffffff, 87%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); + color: #ffffff; - background-color: #494949; } ++ background-color: st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:hover { - background-color: #383838; } ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), 4%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:focus { - background-color: #484c51; } ++ background-color: st-mix(-st-accent-color, st-mix(st-lighten(st-mix(#ffffff, #000000, 9%), 9%), #ffffff, 87%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .user-icon { + border: 2px solid transparent; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: rgba(255, 255, 255, 0.7); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon { - border-color: #3584e4; } ++ border-color: -st-accent-color; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon StIcon { - background-color: rgba(53, 132, 228, 0.3); } ++ background-color: st-transparentize(-st-accent-color, 0.7); } + +.unlock-dialog { + background-color: transparent; } + +.screen-shield-background { + background: black; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); } + +#lockDialogGroup { + background-color: #000000; } + +.unlock-dialog-clock { + color: #ffffff; + spacing: 2em; } + .unlock-dialog-clock .unlock-dialog-clock-time { + font-size: 6.546em; - font-weight: 200; } ++ font-weight: 800; } + .unlock-dialog-clock .unlock-dialog-clock-date { + font-weight: 400; } + .unlock-dialog-clock .unlock-dialog-clock-hint { + margin-top: 2em; + padding: 6px 18px; + border-radius: 16px; + font-weight: bold; } + +#unlockDialogNotifications StButton#vhandle, #unlockDialogNotifications StButton#hhandle { + background-color: rgba(26, 26, 26, 0.3); } + #unlockDialogNotifications StButton#vhandle:hover, #unlockDialogNotifications StButton#vhandle:focus, #unlockDialogNotifications StButton#hhandle:hover, #unlockDialogNotifications StButton#hhandle:focus { + background-color: rgba(26, 26, 26, 0.5); } + #unlockDialogNotifications StButton#vhandle:active, #unlockDialogNotifications StButton#hhandle:active { - background-color: rgba(53, 132, 228, 0.5); } ++ background-color: st-transparentize(-st-accent-color, 0.5); } + +.unlock-dialog-notifications-container { + margin: 12px; + spacing: 6px; + width: 25em; + background-color: transparent; } + .unlock-dialog-notifications-container .summary-notification-stack-scrollview { + padding-top: 0; + padding-bottom: 0; } + .unlock-dialog-notifications-container .notification, + .unlock-dialog-notifications-container .unlock-dialog-notification-source { + padding: 12px 16px; + border: none; + background-color: rgba(255, 255, 255, 0.1); + color: #ffffff; + border-radius: 16px; } + .unlock-dialog-notifications-container .notification.critical, + .unlock-dialog-notifications-container .unlock-dialog-notification-source.critical { + background-color: rgba(255, 255, 255, 0.2); } + +.unlock-dialog-notification-icon { + icon-size: 32px; } + +.unlock-dialog-notification-label { + padding-left: 12px; + padding-right: 0; } + .unlock-dialog-notification-label:rtl { + padding-right: 12px; + padding-left: 0; } + +.unlock-dialog-notification-count-text { + font-weight: bold; + padding: 0 12px; + color: #ffffff; + background-color: rgba(255, 255, 255, 0.1); + border-radius: 999px; } + +.login-dialog .user-widget .user-widget-label, +.unlock-dialog .user-widget .user-widget-label { + color: #ffffff; } + +.login-dialog .user-widget .user-icon, +.unlock-dialog .user-widget .user-icon { + background-color: rgba(255, 255, 255, 0.13); + color: #ffffff; + background-color: rgba(255, 255, 255, 0.3); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); } + +.login-dialog .user-widget.horizontal, +.unlock-dialog .user-widget.horizontal { + spacing: 18px; } + +.login-dialog .user-widget.vertical, +.unlock-dialog .user-widget.vertical { + spacing: 24px; } + .login-dialog .user-widget.vertical .user-widget-label, + .unlock-dialog .user-widget.vertical .user-widget-label { ++ font-weight: 400; ++ font-size: 1.818em; + text-align: center; + margin-bottom: .75em; } + .login-dialog .user-widget.vertical .user-icon, + .unlock-dialog .user-widget.vertical .user-icon { + icon-size: 160px; } + .login-dialog .user-widget.vertical .user-icon StIcon, + .unlock-dialog .user-widget.vertical .user-icon StIcon { - padding: 24px; } ++ padding: 30px; } diff --cc data/theme/gnome-shell-light.css index a9da1e650,000000000..a84dc2289 mode 100644,000000..100644 --- a/data/theme/gnome-shell-light.css +++ b/data/theme/gnome-shell-light.css @@@ -1,3110 -1,0 +1,3219 @@@ +/* This stylesheet is generated, DO NOT EDIT */ +/* Copyright 2009, 2015 Red Hat, Inc. + * + * Portions adapted from Mx's data/style/default.css + * Copyright 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* Global Values */ +stage { + font-size: 1em; + color: #282828; } + +/* Common Stylings */ +#dash .dash-item-container .show-apps, +#dash .dash-item-container .overview-tile, +#dash .dash-item-container .grid-search-result { + background: none; + box-shadow: none; + border: none; + border-radius: 0; + padding: 0; + margin: 0; } + +.app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result, .app-folder, .overview-tile, .grid-search-result, #dash .dash-item-container .show-apps .overview-icon, +#dash .dash-item-container .overview-tile .overview-icon, +#dash .dash-item-container .grid-search-result .overview-icon, .list-search-result, .search-provider-icon, .switcher-list .item-box { + border-radius: 16px; + padding: 6px; + spacing: 6px; + text-align: center; + transition-duration: 100ms; } + +.login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item, .login-dialog-not-listed-button, .unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, - .unlock-dialog .screenshot-ui-show-pointer-button, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, ++.unlock-dialog .screenshot-ui-show-pointer-button, #LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button, #LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button, .icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + border-radius: 8px; + padding: 3px 24px; + font-weight: bold; + transition: border-width 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button, .button { + color: #282828; - background-color: gainsboro; } ++ background-color: st-mix(#282828, whitesmoke, 12%); } + .icon-button:focus, .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus, .screenshot-ui-show-pointer-button:focus, .message .message-header .message-expand-button:focus, + .message .message-header .message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#282828, whitesmoke, 12%), 5%); } + .icon-button:focus:hover, .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .message .message-header .message-expand-button:focus:hover, + .message .message-header .message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button:focus:hover { - background-color: #c9cdd2; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 4%), 5%); } + .icon-button:hover, .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover, .screenshot-ui-show-pointer-button:hover, .message .message-header .message-expand-button:hover, + .message .message-header .message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button:hover { + color: #282828; - background-color: #d2d2d2; } ++ background-color: st-darken(st-mix(#282828, whitesmoke, 12%), 4%); } + .icon-button:insensitive, .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive, .screenshot-ui-show-pointer-button:insensitive, .message .message-header .message-expand-button:insensitive, + .message .message-header .message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: #e4e4e4; } ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(st-mix(#282828, whitesmoke, 12%), 3%); } + .icon-button:selected, .login-dialog-button.cancel-button:selected, .login-dialog-button.switch-user-button:selected, .login-dialog-button.login-dialog-session-list-button:selected, .screenshot-ui-show-pointer-button:selected, .message .message-header .message-expand-button:selected, + .message .message-header .message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button:selected, .icon-button:active, .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active, .screenshot-ui-show-pointer-button:active, .message .message-header .message-expand-button:active, + .message .message-header .message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button:active { + color: #282828; - background-color: #c5c5c5; } ++ background-color: st-darken(st-mix(#282828, whitesmoke, 12%), 9%); } + .icon-button:selected:hover, .login-dialog-button.cancel-button:selected:hover, .login-dialog-button.switch-user-button:selected:hover, .login-dialog-button.login-dialog-session-list-button:selected:hover, .screenshot-ui-show-pointer-button:selected:hover, .message .message-header .message-expand-button:selected:hover, + .message .message-header .message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button:selected:hover, .icon-button:active:hover, .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover, .screenshot-ui-show-pointer-button:active:hover, .message .message-header .message-expand-button:active:hover, + .message .message-header .message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button:active:hover { - background-color: #bbbbbb; } ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 9%), 4%); } + .icon-button:selected:focus, .login-dialog-button.cancel-button:selected:focus, .login-dialog-button.switch-user-button:selected:focus, .login-dialog-button.login-dialog-session-list-button:selected:focus, .screenshot-ui-show-pointer-button:selected:focus, .message .message-header .message-expand-button:selected:focus, + .message .message-header .message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button:selected:focus, .icon-button:active:focus, .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus, .screenshot-ui-show-pointer-button:active:focus, .message .message-header .message-expand-button:active:focus, + .message .message-header .message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button:active:focus { - background-color: #bdc1c6; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 9%), 5%); } + .icon-button:checked, .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked, .screenshot-ui-show-pointer-button:checked, .message .message-header .message-expand-button:checked, + .message .message-header .message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button:checked { + color: #282828; - background-color: #c8c8c8; } ++ background-color: st-darken(st-mix(#282828, whitesmoke, 12%), 8%); } + .icon-button:checked:hover, .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .message .message-header .message-expand-button:checked:hover, + .message .message-header .message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button:checked:hover { - background-color: #bdbdbd; } ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 4%); } + .icon-button:checked:active, .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active, .screenshot-ui-show-pointer-button:checked:active, .message .message-header .message-expand-button:checked:active, + .message .message-header .message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button:checked:active { - background-color: #b1b1b1; } ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 9%); } + +.calendar .calendar-day-heading, .calendar .calendar-day, .calendar .calendar-month-header .calendar-month-label, .icon-button.flat, .flat.login-dialog-button.cancel-button, .flat.login-dialog-button.switch-user-button, .flat.login-dialog-button.login-dialog-session-list-button, .flat.screenshot-ui-show-pointer-button, .message .message-header .flat.message-expand-button, +.message .message-header .flat.message-close-button, .calendar .calendar-month-header .pager-button, .button.flat { + color: #282828; + background-color: whitesmoke; } + .calendar .calendar-day-heading:focus, .calendar .calendar-day:focus, .calendar .calendar-month-header .calendar-month-label:focus, .icon-button.flat:focus, .flat.login-dialog-button.cancel-button:focus, .flat.login-dialog-button.switch-user-button:focus, .flat.login-dialog-button.login-dialog-session-list-button:focus, .flat.screenshot-ui-show-pointer-button:focus, .message .message-header .flat.message-expand-button:focus, + .message .message-header .flat.message-close-button:focus, .calendar .calendar-month-header .pager-button:focus, .button.flat:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(187, 209, 237, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.25), 5%); } + .calendar .calendar-day-heading:focus:hover, .calendar .calendar-day:focus:hover, .calendar .calendar-month-header .calendar-month-label:focus:hover, .icon-button.flat:focus:hover, .flat.login-dialog-button.cancel-button:focus:hover, .flat.login-dialog-button.switch-user-button:focus:hover, .flat.login-dialog-button.login-dialog-session-list-button:focus:hover, .flat.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .flat.message-expand-button:focus:hover, + .message .message-header .flat.message-close-button:focus:hover, .calendar .calendar-month-header .pager-button:focus:hover, .button.flat:focus:hover { - background-color: #d9dde3; } ++ background-color: st-mix(-st-accent-color, st-darken(whitesmoke, 7%), 5%); } + .calendar .calendar-day-heading:hover, .calendar .calendar-day:hover, .calendar .calendar-month-header .calendar-month-label:hover, .icon-button.flat:hover, .flat.login-dialog-button.cancel-button:hover, .flat.login-dialog-button.switch-user-button:hover, .flat.login-dialog-button.login-dialog-session-list-button:hover, .flat.screenshot-ui-show-pointer-button:hover, .message .message-header .flat.message-expand-button:hover, + .message .message-header .flat.message-close-button:hover, .calendar .calendar-month-header .pager-button:hover, .button.flat:hover { + color: #282828; - background-color: #e3e3e3; } ++ background-color: st-darken(whitesmoke, 7%); } + .calendar .calendar-day-heading:insensitive, .calendar .calendar-day:insensitive, .calendar .calendar-month-header .calendar-month-label:insensitive, .icon-button.flat:insensitive, .flat.login-dialog-button.cancel-button:insensitive, .flat.login-dialog-button.switch-user-button:insensitive, .flat.login-dialog-button.login-dialog-session-list-button:insensitive, .flat.screenshot-ui-show-pointer-button:insensitive, .message .message-header .flat.message-expand-button:insensitive, + .message .message-header .flat.message-close-button:insensitive, .calendar .calendar-month-header .pager-button:insensitive, .button.flat:insensitive { - color: rgba(40, 40, 40, 0.4); ++ color: st-transparentize(#282828, 0.6); + background-color: whitesmoke; } + .calendar .calendar-day-heading:selected, .calendar .calendar-day:selected, .calendar .calendar-month-header .calendar-month-label:selected, .icon-button.flat:selected, .flat.login-dialog-button.cancel-button:selected, .flat.login-dialog-button.switch-user-button:selected, .flat.login-dialog-button.login-dialog-session-list-button:selected, .flat.screenshot-ui-show-pointer-button:selected, .message .message-header .flat.message-expand-button:selected, + .message .message-header .flat.message-close-button:selected, .calendar .calendar-month-header .pager-button:selected, .button.flat:selected, .calendar .calendar-day-heading:active, .calendar .calendar-day:active, .calendar .calendar-month-header .calendar-month-label:active, .icon-button.flat:active, .flat.login-dialog-button.cancel-button:active, .flat.login-dialog-button.switch-user-button:active, .flat.login-dialog-button.login-dialog-session-list-button:active, .flat.screenshot-ui-show-pointer-button:active, .message .message-header .flat.message-expand-button:active, + .message .message-header .flat.message-close-button:active, .calendar .calendar-month-header .pager-button:active, .button.flat:active { + color: #282828; - background-color: #dedede; } ++ background-color: st-darken(whitesmoke, 9%); } + .calendar .calendar-day-heading:selected:hover, .calendar .calendar-day:selected:hover, .calendar .calendar-month-header .calendar-month-label:selected:hover, .icon-button.flat:selected:hover, .flat.login-dialog-button.cancel-button:selected:hover, .flat.login-dialog-button.switch-user-button:selected:hover, .flat.login-dialog-button.login-dialog-session-list-button:selected:hover, .flat.screenshot-ui-show-pointer-button:selected:hover, .message .message-header .flat.message-expand-button:selected:hover, + .message .message-header .flat.message-close-button:selected:hover, .calendar .calendar-month-header .pager-button:selected:hover, .button.flat:selected:hover, .calendar .calendar-day-heading:active:hover, .calendar .calendar-day:active:hover, .calendar .calendar-month-header .calendar-month-label:active:hover, .icon-button.flat:active:hover, .flat.login-dialog-button.cancel-button:active:hover, .flat.login-dialog-button.switch-user-button:active:hover, .flat.login-dialog-button.login-dialog-session-list-button:active:hover, .flat.screenshot-ui-show-pointer-button:active:hover, .message .message-header .flat.message-expand-button:active:hover, + .message .message-header .flat.message-close-button:active:hover, .calendar .calendar-month-header .pager-button:active:hover, .button.flat:active:hover { - background-color: #cccccc; } ++ background-color: st-darken(st-darken(whitesmoke, 9%), 7%); } + .calendar .calendar-day-heading:selected:focus, .calendar .calendar-day:selected:focus, .calendar .calendar-month-header .calendar-month-label:selected:focus, .icon-button.flat:selected:focus, .flat.login-dialog-button.cancel-button:selected:focus, .flat.login-dialog-button.switch-user-button:selected:focus, .flat.login-dialog-button.login-dialog-session-list-button:selected:focus, .flat.screenshot-ui-show-pointer-button:selected:focus, .message .message-header .flat.message-expand-button:selected:focus, + .message .message-header .flat.message-close-button:selected:focus, .calendar .calendar-month-header .pager-button:selected:focus, .button.flat:selected:focus, .calendar .calendar-day-heading:active:focus, .calendar .calendar-day:active:focus, .calendar .calendar-month-header .calendar-month-label:active:focus, .icon-button.flat:active:focus, .flat.login-dialog-button.cancel-button:active:focus, .flat.login-dialog-button.switch-user-button:active:focus, .flat.login-dialog-button.login-dialog-session-list-button:active:focus, .flat.screenshot-ui-show-pointer-button:active:focus, .message .message-header .flat.message-expand-button:active:focus, + .message .message-header .flat.message-close-button:active:focus, .calendar .calendar-month-header .pager-button:active:focus, .button.flat:active:focus { - background-color: #d4d9de; } ++ background-color: st-mix(-st-accent-color, st-darken(whitesmoke, 9%), 5%); } + .calendar .calendar-day-heading:checked, .calendar .calendar-day:checked, .calendar .calendar-month-header .calendar-month-label:checked, .icon-button.flat:checked, .flat.login-dialog-button.cancel-button:checked, .flat.login-dialog-button.switch-user-button:checked, .flat.login-dialog-button.login-dialog-session-list-button:checked, .flat.screenshot-ui-show-pointer-button:checked, .message .message-header .flat.message-expand-button:checked, + .message .message-header .flat.message-close-button:checked, .calendar .calendar-month-header .pager-button:checked, .button.flat:checked { + color: #282828; - background-color: #e1e1e1; } ++ background-color: st-darken(whitesmoke, 8%); } + .calendar .calendar-day-heading:checked:hover, .calendar .calendar-day:checked:hover, .calendar .calendar-month-header .calendar-month-label:checked:hover, .icon-button.flat:checked:hover, .flat.login-dialog-button.cancel-button:checked:hover, .flat.login-dialog-button.switch-user-button:checked:hover, .flat.login-dialog-button.login-dialog-session-list-button:checked:hover, .flat.screenshot-ui-show-pointer-button:checked:hover, .message .message-header .flat.message-expand-button:checked:hover, + .message .message-header .flat.message-close-button:checked:hover, .calendar .calendar-month-header .pager-button:checked:hover, .button.flat:checked:hover { - background-color: #cfcfcf; } ++ background-color: st-darken(st-darken(whitesmoke, 8%), 7%); } + .calendar .calendar-day-heading:checked:active, .calendar .calendar-day:checked:active, .calendar .calendar-month-header .calendar-month-label:checked:active, .icon-button.flat:checked:active, .flat.login-dialog-button.cancel-button:checked:active, .flat.login-dialog-button.switch-user-button:checked:active, .flat.login-dialog-button.login-dialog-session-list-button:checked:active, .flat.screenshot-ui-show-pointer-button:checked:active, .message .message-header .flat.message-expand-button:checked:active, + .message .message-header .flat.message-close-button:checked:active, .calendar .calendar-month-header .pager-button:checked:active, .button.flat:checked:active { - background-color: #cacaca; } ++ background-color: st-darken(st-darken(whitesmoke, 8%), 9%); } + +.keyboard-brightness-level .button:checked, .quick-menu-toggle .quick-toggle-arrow:checked, .quick-toggle:checked, .calendar .calendar-day.calendar-today, .icon-button.default, .default.login-dialog-button.cancel-button, .default.login-dialog-button.switch-user-button, .default.login-dialog-button.login-dialog-session-list-button, .default.screenshot-ui-show-pointer-button, .message .message-header .default.message-expand-button, +.message .message-header .default.message-close-button, .calendar .calendar-month-header .default.pager-button, .button.default { - color: #ffffff; - background-color: #1c71d8; } ++ color: -st-accent-fg-color; ++ background-color: -st-accent-color; } + .keyboard-brightness-level .button:focus:checked, .quick-menu-toggle .quick-toggle-arrow:focus:checked, .quick-toggle:focus:checked, .calendar .calendar-day.calendar-today:focus, .icon-button.default:focus, .default.login-dialog-button.cancel-button:focus, .default.login-dialog-button.switch-user-button:focus, .default.login-dialog-button.login-dialog-session-list-button:focus, .default.screenshot-ui-show-pointer-button:focus, .message .message-header .default.message-expand-button:focus, + .message .message-header .default.message-close-button:focus, .calendar .calendar-month-header .default.pager-button:focus, .button.default:focus { - color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - box-shadow: inset 0 0 0 2px #134e94 !important; - background-color: #1c71d8; } ++ color: -st-accent-fg-color; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ box-shadow: inset 0 0 0 2px st-darken(-st-accent-color, 15%) !important; ++ background-color: st-mix(-st-accent-color, -st-accent-color, 5%); } + .keyboard-brightness-level .button:focus:hover:checked, .quick-menu-toggle .quick-toggle-arrow:focus:hover:checked, .quick-toggle:focus:hover:checked, .calendar .calendar-day.calendar-today:focus:hover, .icon-button.default:focus:hover, .default.login-dialog-button.cancel-button:focus:hover, .default.login-dialog-button.switch-user-button:focus:hover, .default.login-dialog-button.login-dialog-session-list-button:focus:hover, .default.screenshot-ui-show-pointer-button:focus:hover, .message .message-header .default.message-expand-button:focus:hover, + .message .message-header .default.message-close-button:focus:hover, .calendar .calendar-month-header .default.pager-button:focus:hover, .button.default:focus:hover { - background-color: #1a68c7; } ++ background-color: st-mix(-st-accent-color, st-darken(-st-accent-color, 4%), 5%); } + .keyboard-brightness-level .button:hover:checked, .quick-menu-toggle .quick-toggle-arrow:hover:checked, .quick-toggle:hover:checked, .calendar .calendar-day.calendar-today:hover, .icon-button.default:hover, .default.login-dialog-button.cancel-button:hover, .default.login-dialog-button.switch-user-button:hover, .default.login-dialog-button.login-dialog-session-list-button:hover, .default.screenshot-ui-show-pointer-button:hover, .message .message-header .default.message-expand-button:hover, + .message .message-header .default.message-close-button:hover, .calendar .calendar-month-header .default.pager-button:hover, .button.default:hover { - color: #ffffff; - background-color: #1a68c6; } ++ color: -st-accent-fg-color; ++ background-color: st-darken(-st-accent-color, 4%); } + .keyboard-brightness-level .button:insensitive:checked, .quick-menu-toggle .quick-toggle-arrow:insensitive:checked, .quick-toggle:insensitive:checked, .calendar .calendar-day.calendar-today:insensitive, .icon-button.default:insensitive, .default.login-dialog-button.cancel-button:insensitive, .default.login-dialog-button.switch-user-button:insensitive, .default.login-dialog-button.login-dialog-session-list-button:insensitive, .default.screenshot-ui-show-pointer-button:insensitive, .message .message-header .default.message-expand-button:insensitive, + .message .message-header .default.message-close-button:insensitive, .calendar .calendar-month-header .default.pager-button:insensitive, .button.default:insensitive { - color: rgba(255, 255, 255, 0.4); - background-color: #2178e2; } ++ color: st-transparentize(-st-accent-fg-color, 0.6); ++ background-color: st-lighten(-st-accent-color, 3%); } + .keyboard-brightness-level .button:active:checked, .quick-menu-toggle .quick-toggle-arrow:active:checked, .quick-toggle:active:checked, .calendar .calendar-day.calendar-today:active, .icon-button.default:active, .default.login-dialog-button.cancel-button:active, .default.login-dialog-button.switch-user-button:active, .default.login-dialog-button.login-dialog-session-list-button:active, .default.screenshot-ui-show-pointer-button:active, .message .message-header .default.message-expand-button:active, + .message .message-header .default.message-close-button:active, .calendar .calendar-month-header .default.pager-button:active, .button.default:active { - color: #ffffff; - background-color: #175caf; } ++ color: -st-accent-fg-color; ++ background-color: st-darken(-st-accent-color, 9%); } + .keyboard-brightness-level .button:active:hover:checked, .quick-menu-toggle .quick-toggle-arrow:active:hover:checked, .quick-toggle:active:hover:checked, .calendar .calendar-day.calendar-today:active:hover, .icon-button.default:active:hover, .default.login-dialog-button.cancel-button:active:hover, .default.login-dialog-button.switch-user-button:active:hover, .default.login-dialog-button.login-dialog-session-list-button:active:hover, .default.screenshot-ui-show-pointer-button:active:hover, .message .message-header .default.message-expand-button:active:hover, + .message .message-header .default.message-close-button:active:hover, .calendar .calendar-month-header .default.pager-button:active:hover, .button.default:active:hover { - background-color: #14529d; } ++ background-color: st-darken(st-darken(-st-accent-color, 9%), 4%); } + .keyboard-brightness-level .button:active:focus:checked, .quick-menu-toggle .quick-toggle-arrow:active:focus:checked, .quick-toggle:active:focus:checked, .calendar .calendar-day.calendar-today:active:focus, .icon-button.default:active:focus, .default.login-dialog-button.cancel-button:active:focus, .default.login-dialog-button.switch-user-button:active:focus, .default.login-dialog-button.login-dialog-session-list-button:active:focus, .default.screenshot-ui-show-pointer-button:active:focus, .message .message-header .default.message-expand-button:active:focus, + .message .message-header .default.message-close-button:active:focus, .calendar .calendar-month-header .default.pager-button:active:focus, .button.default:active:focus { - background-color: #175db1; } ++ background-color: st-mix(-st-accent-color, st-darken(-st-accent-color, 9%), 5%); } + +.popup-sub-menu .popup-menu-item, .popup-menu-item { + font-weight: normal; + spacing: 6px; + transition-duration: 100ms; + padding: 9px 12px; } + - .calendar, .datemenu-today-button, .lg-extension, .quick-toggle-menu, .message, .events-button, ++#LookingGlassExtensions .lg-extension, #LookingGlassWindows .lg-window, .calendar, .datemenu-today-button, .quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + border-radius: 12px; + padding: 0.818em; + margin: 4px; + background-color: #ffffff; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03); + border: 1px solid rgba(0, 0, 0, 0.09); } + - .lg-extension, .quick-toggle-menu, .message, .events-button, ++.quick-toggle-menu, .message, .events-button, +.world-clocks-button, +.weather-button { + color: #282828; + background-color: #ffffff; } - .lg-extension:hover, .quick-toggle-menu:hover, .message:hover, .events-button:hover, ++ .quick-toggle-menu:hover, .message:hover, .events-button:hover, + .world-clocks-button:hover, + .weather-button:hover { + color: #282828; - background-color: whitesmoke; } - .lg-extension:active, .quick-toggle-menu:active, .message:active, .events-button:active, ++ background-color: st-darken(#ffffff, 4%); } ++ .quick-toggle-menu:active, .message:active, .events-button:active, + .world-clocks-button:active, + .weather-button:active { + color: #282828; - background-color: #e8e8e8; } - .lg-extension:active:hover, .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, ++ background-color: st-darken(#ffffff, 9%); } ++ .quick-toggle-menu:active:hover, .message:active:hover, .events-button:active:hover, + .world-clocks-button:active:hover, + .weather-button:active:hover { - background-color: #dedede; } - .lg-extension:active:focus, .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, ++ background-color: st-darken(st-darken(#ffffff, 9%), 4%); } ++ .quick-toggle-menu:active:focus, .message:active:focus, .events-button:active:focus, + .world-clocks-button:active:focus, + .weather-button:active:focus { - background-color: #dee2e7; } - .lg-extension:focus, .quick-toggle-menu:focus, .message:focus, .events-button:focus, ++ background-color: st-mix(-st-accent-color, st-darken(#ffffff, 9%), 5%); } ++ .quick-toggle-menu:focus, .message:focus, .events-button:focus, + .world-clocks-button:focus, + .weather-button:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #f4f8fd; } - .lg-extension:focus:hover, .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #ffffff, 5%); } ++ .quick-toggle-menu:focus:hover, .message:focus:hover, .events-button:focus:hover, + .world-clocks-button:focus:hover, + .weather-button:focus:hover { - background-color: #eaeef3; } - .lg-extension:insensitive, .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, ++ background-color: st-mix(-st-accent-color, st-darken(#ffffff, 4%), 5%); } ++ .quick-toggle-menu:insensitive, .message:insensitive, .events-button:insensitive, + .world-clocks-button:insensitive, + .weather-button:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: white; } ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(#ffffff, 3%); } + +.calendar, .datemenu-today-button { + border: 1px solid transparent !important; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .calendar:insensitive, .datemenu-today-button:insensitive { + background-color: transparent !important; } + .calendar:hover, .datemenu-today-button:hover { + color: #282828; - background-color: #e3e3e3; } ++ background-color: st-darken(whitesmoke, 7%); } + .calendar:active, .datemenu-today-button:active { + color: #282828; - background-color: #dedede; } ++ background-color: st-darken(whitesmoke, 9%); } + .calendar:active:hover, .datemenu-today-button:active:hover { - background-color: #cccccc; } ++ background-color: st-darken(st-darken(whitesmoke, 9%), 7%); } + .calendar:active:focus, .datemenu-today-button:active:focus { - background-color: #d4d9de; } ++ background-color: st-mix(-st-accent-color, st-darken(whitesmoke, 9%), 5%); } + .calendar:focus, .datemenu-today-button:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #f4f8fd; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #ffffff, 5%); } + .calendar:focus:hover, .datemenu-today-button:focus:hover { - background-color: #eaeef3; } ++ background-color: st-mix(-st-accent-color, st-darken(#ffffff, 4%), 5%); } + .calendar:insensitive, .datemenu-today-button:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: white; } ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(#ffffff, 3%); } + +.unlock-dialog .login-dialog-prompt-entry, .login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry, .lg-dialog StEntry, StEntry { + border-radius: 8px; + padding: 9px 9px; - selection-background-color: #1c71d8; - selected-color: #ffffff; } ++ selection-background-color: st-transparentize(-st-accent-color, 0.7); ++ selected-color: #282828; } + +StEntry { + background-color: gainsboro; + color: rgba(40, 40, 40, 0.7); } + StEntry:hover { + background-color: #d2d2d2; + color: #282828; } + StEntry:focus { - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, gainsboro, 5%); + color: #282828; } + StEntry:insensitive { + background-color: #e4e4e4; + color: rgba(40, 40, 40, 0.5); } + StEntry StLabel.hint-text { + color: rgba(40, 40, 40, 0.7); } + - .modal-dialog .modal-dialog-linked-button, .notification-button { ++.notification-button, .message .message-header .message-expand-button, ++.message .message-header .message-close-button { ++ font-weight: bold; ++ padding: 6px 12px; ++ border-radius: 8px; ++ color: #282828; ++ background-color: rgba(40, 40, 40, 0.15); } ++ .notification-button:focus, .message .message-header .message-expand-button:focus, ++ .message .message-header .message-close-button:focus { ++ color: #282828; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.15), 5%); } ++ .notification-button:focus:hover, .message .message-header .message-expand-button:focus:hover, ++ .message .message-header .message-close-button:focus:hover { ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.3), 5%); } ++ .notification-button:hover, .message .message-header .message-expand-button:hover, ++ .message .message-header .message-close-button:hover { ++ color: #282828; ++ background-color: rgba(40, 40, 40, 0.3); } ++ .notification-button:active, .message .message-header .message-expand-button:active, ++ .message .message-header .message-close-button:active { ++ color: #282828; ++ background-color: rgba(40, 40, 40, 0.2); } ++ .notification-button:active:hover, .message .message-header .message-expand-button:active:hover, ++ .message .message-header .message-close-button:active:hover { ++ background-color: rgba(40, 40, 40, 0.2); } ++ .notification-button:active:focus, .message .message-header .message-expand-button:active:focus, ++ .message .message-header .message-close-button:active:focus { ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.2), 5%); } ++ .notification-button:checked, .message .message-header .message-expand-button:checked, ++ .message .message-header .message-close-button:checked { ++ color: #282828; ++ background-color: st-darken(st-mix(#282828, whitesmoke, 12%), 8%); } ++ .notification-button:checked:hover, .message .message-header .message-expand-button:checked:hover, ++ .message .message-header .message-close-button:checked:hover { ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 4%); } ++ .notification-button:checked:active, .message .message-header .message-expand-button:checked:active, ++ .message .message-header .message-close-button:checked:active { ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 9%); } ++ .notification-button:insensitive, .message .message-header .message-expand-button:insensitive, ++ .message .message-header .message-close-button:insensitive { ++ color: st-transparentize(#282828, 0.6); ++ background-color: rgba(40, 40, 40, 0.1); } ++ ++.modal-dialog .modal-dialog-linked-button { ++ font-weight: bold; + padding: 12px; - font-weight: bold !important; ++ border-radius: 12px; + color: #282828; + background-color: rgba(40, 40, 40, 0.1); } - .modal-dialog .modal-dialog-linked-button:ltr, .notification-button:ltr { - margin-right: 1px; } - .modal-dialog .modal-dialog-linked-button:rtl, .notification-button:rtl { - margin-left: 1px; } - .modal-dialog .modal-dialog-linked-button:focus, .notification-button:focus { ++ .modal-dialog .modal-dialog-linked-button:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(34, 77, 128, 0.145); } - .modal-dialog .modal-dialog-linked-button:focus:hover, .notification-button:focus:hover { - background-color: rgba(35, 71, 116, 0.1735); } - .modal-dialog .modal-dialog-linked-button:hover, .notification-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.1), 5%); } ++ .modal-dialog .modal-dialog-linked-button:focus:hover { ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.13), 5%); } ++ .modal-dialog .modal-dialog-linked-button:hover { + color: #282828; + background-color: rgba(40, 40, 40, 0.13); } - .modal-dialog .modal-dialog-linked-button:active, .notification-button:active { ++ .modal-dialog .modal-dialog-linked-button:active { + color: #282828; + background-color: rgba(40, 40, 40, 0.16); } - .modal-dialog .modal-dialog-linked-button:active:hover, .notification-button:active:hover { ++ .modal-dialog .modal-dialog-linked-button:active:hover { + background-color: rgba(40, 40, 40, 0.19); } - .modal-dialog .modal-dialog-linked-button:active:focus, .notification-button:active:focus { - background-color: rgba(35, 68, 106, 0.202); } - .modal-dialog .modal-dialog-linked-button:checked, .notification-button:checked { ++ .modal-dialog .modal-dialog-linked-button:active:focus { ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.16), 5%); } ++ .modal-dialog .modal-dialog-linked-button:checked { + color: #282828; - background-color: #c8c8c8; } - .modal-dialog .modal-dialog-linked-button:checked:hover, .notification-button:checked:hover { - background-color: #bdbdbd; } - .modal-dialog .modal-dialog-linked-button:checked:active, .notification-button:checked:active { - background-color: #b1b1b1; } - .modal-dialog .modal-dialog-linked-button:insensitive, .notification-button:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: #e4e4e4; } - .modal-dialog .modal-dialog-linked-button:first-child:ltr, .notification-button:first-child:ltr { - border-radius: 0 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:ltr, .notification-button:last-child:ltr { - border-radius: 0 0 15px; - margin-right: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:rtl, .notification-button:first-child:rtl { - border-radius: 0 0 15px; } - .modal-dialog .modal-dialog-linked-button:last-child:rtl, .notification-button:last-child:rtl { - border-radius: 0 0 0 15px; - margin-left: 0 !important; } - .modal-dialog .modal-dialog-linked-button:first-child:last-child, .notification-button:first-child:last-child { - border-radius: 0 0 15px 15px; - margin-left: 0 !important; - margin-right: 0 !important; } ++ background-color: st-darken(st-mix(#282828, whitesmoke, 12%), 8%); } ++ .modal-dialog .modal-dialog-linked-button:checked:hover { ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 4%); } ++ .modal-dialog .modal-dialog-linked-button:checked:active { ++ background-color: st-darken(st-darken(st-mix(#282828, whitesmoke, 12%), 8%), 9%); } ++ .modal-dialog .modal-dialog-linked-button:insensitive { ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(st-mix(#282828, whitesmoke, 12%), 3%); } + +.dash-label, .window-caption, .screenshot-ui-tooltip { + background-color: rgba(0, 0, 0, 0.9); + border: 1px solid rgba(255, 255, 255, 0.1); + color: #ffffff; + border-radius: 999px; + padding: 6px 12px; + text-align: center; } + +/* General Typography */ - .login-dialog .user-widget.vertical .user-widget-label, - .unlock-dialog .user-widget.vertical .user-widget-label, .unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { ++.unlock-dialog-clock .unlock-dialog-clock-date, .app-folder-dialog .folder-name-container .folder-name-label, .app-folder-dialog .folder-name-container .folder-name-entry, .search-statustext { + font-weight: 800; + font-size: 1.818em; } + - .conflicting-session-dialog-content .conflicting-session-dialog-title, .lg-debug-flags-header, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { ++.conflicting-session-dialog-content .conflicting-session-dialog-title, .message-dialog-content .message-dialog-title, .message-list .message-list-placeholder, .datemenu-today-button .date-label { + font-weight: 800; + font-size: 1.364em; } + +.login-dialog .user-widget.horizontal .user-widget-label, +.unlock-dialog .user-widget.horizontal .user-widget-label, .quick-toggle-menu .header .title { + font-weight: 700; + font-size: 1.364em; } + - .login-dialog-auth-list-label, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { ++.login-dialog-auth-list-label, #LookingGlassDebugFlags .lg-debug-flags-header, #LookingGlassExtensions .lg-extensions-none, .word-suggestions, .bt-menu-placeholder.popup-menu-item, .message-dialog-content .message-dialog-title.lightweight, .headline { + font-weight: 700; + font-size: 1.182em; } + - .login-dialog-not-listed-label, .lg-extension-name, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { ++.login-dialog-not-listed-label, #LookingGlassExtensions .lg-extension .lg-extension-name, #LookingGlassWindows .lg-window .lg-window-name, #LookingGlassPropertyInspector .lg-obj-inspector-title, .background-app-item .title, .osd-window, .dialog-list .dialog-list-title, .message-list-controls, .weather-button .weather-box .weather-header-box .weather-header, .world-clocks-button .world-clocks-header, .events-button .events-box .events-list .event-box .event-summary, .events-button .events-box .events-title, .calendar .calendar-month-header .calendar-month-label { + font-weight: 700; + font-size: 1em; } + +.quick-toggle-menu .header .subtitle, .app-menu .popup-inactive-menu-item:first-child > StLabel { + font-weight: 700; + font-size: 0.818em; } + +.lg-completions-text, .caps-lock-warning-label, .background-app-item .subtitle, .quick-toggle StBoxLayout > .quick-toggle-subtitle, .screenshot-ui-type-button .icon-label-button-container, .prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label, .run-dialog .run-dialog-description, .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description, .message .message-header .message-header-content .event-time, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .events-button .events-box .events-list .event-box .event-time { + font-weight: 400; + font-size: 0.818em; } + +.weather-button .weather-box .weather-grid .weather-forecast-time, .calendar .calendar-week-number, .calendar .calendar-day-heading, .calendar .calendar-day { + font-weight: 400; + font-size: 0.818em; } + - #EvalBox { ++#LookingGlassDebugFlags .lg-debug-flag-button StLabel, #LookingGlassEvaluator .evaluator-results, .lg-dialog .actor-link { + font-family: monospace; } + +.unlock-dialog-clock .unlock-dialog-clock-time, #panel, .weather-button .weather-box .weather-grid .weather-forecast-temp, .world-clocks-button .world-clocks-grid .world-clocks-timezone, .world-clocks-button .world-clocks-grid .world-clocks-time, .events-button .events-box .events-list .event-box .event-time, .calendar .calendar-day-heading, .calendar .calendar-day { + font-feature-settings: "tnum"; } + +/* OSD Elements */ +#LookingGlassDialog, .screenshot-ui-panel, .workspace-switcher, .switcher-list, .resize-popup, .osd-window { + color: #ffffff; + background-color: #353535; + border: 1px solid rgba(255, 255, 255, 0.02); + border-radius: 999px; + padding: 12px; } + +.lg-dialog StEntry { + background-color: #4d4d4d; + color: rgba(255, 255, 255, 0.7); } + .lg-dialog StEntry:hover { + background-color: #575757; + color: #ffffff; } + .lg-dialog StEntry:focus { - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #4b4f54; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #4d4d4d, 5%); + color: #ffffff; } + .lg-dialog StEntry:insensitive { + background-color: #454545; + color: rgba(255, 255, 255, 0.5); } + .lg-dialog StEntry StLabel.hint-text { + color: rgba(255, 255, 255, 0.7); } + - #LookingGlassDialog .notebook-tab, #LookingGlassDialog > #Toolbar .lg-toolbar-button { ++#LookingGlassDebugFlags .lg-debug-flag-button, #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++#LookingGlassPropertyInspector .lg-obj-inspector-button, #LookingGlassDialog > #Toolbar .lg-toolbar-button { + color: #ffffff; - background-color: #4d4d4d; } - #LookingGlassDialog .notebook-tab:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { ++ background-color: st-mix(#ffffff, #353535, 12%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #4b4f54; } - #LookingGlassDialog .notebook-tab:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { - background-color: #54585e; } - #LookingGlassDialog .notebook-tab:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#ffffff, #353535, 12%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:focus:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:focus:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:focus:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 12%), 4%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:hover { + color: #ffffff; - background-color: #575757; } - #LookingGlassDialog .notebook-tab:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 12%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active { + color: #ffffff; - background-color: #646464; } - #LookingGlassDialog .notebook-tab:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { - background-color: #6e6e6e; } - #LookingGlassDialog .notebook-tab:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { - background-color: #60656a; } - #LookingGlassDialog .notebook-tab:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 12%), 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 12%), 9%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:active:focus, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:active:focus, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:active:focus, #LookingGlassDialog > #Toolbar .lg-toolbar-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 12%), 9%), 5%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked { + color: #ffffff; - background-color: #616161; } - #LookingGlassDialog .notebook-tab:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { - background-color: #6c6c6c; } - #LookingGlassDialog .notebook-tab:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { - background-color: #787878; } - #LookingGlassDialog .notebook-tab:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { - color: rgba(255, 255, 255, 0.4); - background-color: #454545; } - - .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { ++ background-color: st-lighten(st-mix(#ffffff, #353535, 12%), 8%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:hover, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:hover, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:hover, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 12%), 8%), 4%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:checked:active, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:checked:active, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:checked:active, #LookingGlassDialog > #Toolbar .lg-toolbar-button:checked:active { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 12%), 8%), 9%); } ++ #LookingGlassDebugFlags .lg-debug-flag-button:insensitive, #LookingGlassPropertyInspector .lg-obj-inspector-close-button:insensitive, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button:insensitive, #LookingGlassDialog > #Toolbar .lg-toolbar-button:insensitive { ++ color: st-transparentize(#ffffff, 0.6); ++ background-color: st-darken(st-mix(#ffffff, #353535, 12%), 3%); } ++ ++#LookingGlassDialog .notebook-tab, .screenshot-ui-show-pointer-button, .screenshot-ui-type-button { + color: #ffffff; + background-color: #353535; } - .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { ++ #LookingGlassDialog .notebook-tab:focus, .screenshot-ui-show-pointer-button:focus, .screenshot-ui-type-button:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(46, 69, 97, 0.2875); } - .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { - background-color: #44494e; } - .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(53, 53, 53, 0.25), 5%); } ++ #LookingGlassDialog .notebook-tab:focus:hover, .screenshot-ui-show-pointer-button:focus:hover, .screenshot-ui-type-button:focus:hover { ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 7%), 5%); } ++ #LookingGlassDialog .notebook-tab:hover, .screenshot-ui-show-pointer-button:hover, .screenshot-ui-type-button:hover { + color: #ffffff; - background-color: #474747; } - .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { ++ background-color: st-lighten(#353535, 7%); } ++ #LookingGlassDialog .notebook-tab:active, .screenshot-ui-show-pointer-button:active, .screenshot-ui-type-button:active { + color: #ffffff; - background-color: #4c4c4c; } - .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { - background-color: #5e5e5e; } - .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { - background-color: #494e53; } - .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { ++ background-color: st-lighten(#353535, 9%); } ++ #LookingGlassDialog .notebook-tab:active:hover, .screenshot-ui-show-pointer-button:active:hover, .screenshot-ui-type-button:active:hover { ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } ++ #LookingGlassDialog .notebook-tab:active:focus, .screenshot-ui-show-pointer-button:active:focus, .screenshot-ui-type-button:active:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } ++ #LookingGlassDialog .notebook-tab:checked, .screenshot-ui-show-pointer-button:checked, .screenshot-ui-type-button:checked { + color: #ffffff; - background-color: #494949; } - .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { - background-color: #5b5b5b; } - .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { - background-color: #606060; } - .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { - color: rgba(255, 255, 255, 0.4); ++ background-color: st-lighten(#353535, 8%); } ++ #LookingGlassDialog .notebook-tab:checked:hover, .screenshot-ui-show-pointer-button:checked:hover, .screenshot-ui-type-button:checked:hover { ++ background-color: st-lighten(st-lighten(#353535, 8%), 7%); } ++ #LookingGlassDialog .notebook-tab:checked:active, .screenshot-ui-show-pointer-button:checked:active, .screenshot-ui-type-button:checked:active { ++ background-color: st-lighten(st-lighten(#353535, 8%), 9%); } ++ #LookingGlassDialog .notebook-tab:insensitive, .screenshot-ui-show-pointer-button:insensitive, .screenshot-ui-type-button:insensitive { ++ color: st-transparentize(#ffffff, 0.6); + background-color: #353535; } + +/* System Elements */ +.login-dialog .login-dialog-prompt-entry, .app-folder-dialog .folder-name-container .folder-name-entry, .search-entry { + background-color: #4c4c4c; + color: rgba(245, 245, 245, 0.7); } + .login-dialog .login-dialog-prompt-entry:hover, .app-folder-dialog .folder-name-container .folder-name-entry:hover, .search-entry:hover { + background-color: #565656; + color: whitesmoke; } + .login-dialog .login-dialog-prompt-entry:focus, .app-folder-dialog .folder-name-container .folder-name-entry:focus, .search-entry:focus { - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #4a4e53; ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, #4c4c4c, 5%); + color: whitesmoke; } + .login-dialog .login-dialog-prompt-entry:insensitive, .app-folder-dialog .folder-name-container .folder-name-entry:insensitive, .search-entry:insensitive { + background-color: #444444; + color: rgba(245, 245, 245, 0.5); } + .login-dialog .login-dialog-prompt-entry StLabel.hint-text, .app-folder-dialog .folder-name-container .folder-name-entry StLabel.hint-text, .search-entry StLabel.hint-text { + color: rgba(245, 245, 245, 0.7); } + +.login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button { + color: whitesmoke; - background-color: #4c4c4c; } ++ background-color: st-mix(whitesmoke, #353535, 12%); } + .login-dialog-button.cancel-button:insensitive, .login-dialog-button.switch-user-button:insensitive, .login-dialog-button.login-dialog-session-list-button:insensitive { - color: rgba(245, 245, 245, 0.4); - background-color: #545454; } ++ color: st-transparentize(whitesmoke, 0.6); ++ background-color: st-lighten(st-mix(whitesmoke, #353535, 12%), 3%); } + .login-dialog-button.cancel-button:focus, .login-dialog-button.switch-user-button:focus, .login-dialog-button.login-dialog-session-list-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #4a4e53; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #353535, 12%), 5%); } + .login-dialog-button.cancel-button:focus:hover, .login-dialog-button.switch-user-button:focus:hover, .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: #404449; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(whitesmoke, #353535, 12%), 4%), 5%); } + .login-dialog-button.cancel-button:hover, .login-dialog-button.switch-user-button:hover, .login-dialog-button.login-dialog-session-list-button:hover { + color: whitesmoke; - background-color: #424242; } ++ background-color: st-darken(st-mix(whitesmoke, #353535, 12%), 4%); } + .login-dialog-button.cancel-button:active, .login-dialog-button.switch-user-button:active, .login-dialog-button.login-dialog-session-list-button:active { + color: whitesmoke; - background-color: #353535; } ++ background-color: st-darken(st-mix(whitesmoke, #353535, 12%), 9%); } + .login-dialog-button.cancel-button:active:hover, .login-dialog-button.switch-user-button:active:hover, .login-dialog-button.login-dialog-session-list-button:active:hover { - background-color: #2b2b2b; } ++ background-color: st-darken(st-darken(st-mix(whitesmoke, #353535, 12%), 9%), 4%); } + .login-dialog-button.cancel-button:active:focus, .login-dialog-button.switch-user-button:active:focus, .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: #34383d; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(whitesmoke, #353535, 12%), 9%), 5%); } + .login-dialog-button.cancel-button:checked, .login-dialog-button.switch-user-button:checked, .login-dialog-button.login-dialog-session-list-button:checked { + color: whitesmoke; - background-color: #383838; } ++ background-color: st-darken(st-mix(whitesmoke, #353535, 12%), 8%); } + .login-dialog-button.cancel-button:checked:hover, .login-dialog-button.switch-user-button:checked:hover, .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #2d2d2d; } ++ background-color: st-darken(st-darken(st-mix(whitesmoke, #353535, 12%), 8%), 4%); } + .login-dialog-button.cancel-button:checked:active, .login-dialog-button.switch-user-button:checked:active, .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #212121; } ++ background-color: st-darken(st-darken(st-mix(whitesmoke, #353535, 12%), 8%), 9%); } + +/* Lockscreen Elements */ +.unlock-dialog .button, +.unlock-dialog .icon-button, +.unlock-dialog .calendar .calendar-month-header .pager-button, +.calendar .calendar-month-header .unlock-dialog .pager-button, +.unlock-dialog .message .message-header .message-expand-button, +.message .message-header .unlock-dialog .message-expand-button, +.unlock-dialog .message .message-header .message-close-button, +.message .message-header .unlock-dialog .message-close-button, +.unlock-dialog .screenshot-ui-show-pointer-button, +.unlock-dialog .login-dialog-button.cancel-button, +.unlock-dialog .login-dialog-button.switch-user-button, +.unlock-dialog .login-dialog-button.login-dialog-session-list-button { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.1); } + .unlock-dialog .button:focus, + .unlock-dialog .icon-button:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus, + .unlock-dialog .message .message-header .message-expand-button:focus, + .message .message-header .unlock-dialog .message-expand-button:focus, + .unlock-dialog .message .message-header .message-close-button:focus, + .message .message-header .unlock-dialog .message-close-button:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:focus, + .unlock-dialog .login-dialog-button.cancel-button:focus, + .unlock-dialog .login-dialog-button.switch-user-button:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(137, 179, 231, 0.145); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.1), 5%); } + .unlock-dialog .button:focus:hover, + .unlock-dialog .icon-button:focus:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:focus:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:focus:hover, + .unlock-dialog .message .message-header .message-expand-button:focus:hover, + .message .message-header .unlock-dialog .message-expand-button:focus:hover, + .unlock-dialog .message .message-header .message-close-button:focus:hover, + .message .message-header .unlock-dialog .message-close-button:focus:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:focus:hover, + .unlock-dialog .login-dialog-button.cancel-button:focus:hover, + .unlock-dialog .login-dialog-button.switch-user-button:focus:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:focus:hover { - background-color: rgba(152, 188, 233, 0.1735); } ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.13), 5%); } + .unlock-dialog .button:hover, + .unlock-dialog .icon-button:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:hover, + .unlock-dialog .message .message-header .message-expand-button:hover, + .message .message-header .unlock-dialog .message-expand-button:hover, + .unlock-dialog .message .message-header .message-close-button:hover, + .message .message-header .unlock-dialog .message-close-button:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:hover, + .unlock-dialog .login-dialog-button.cancel-button:hover, + .unlock-dialog .login-dialog-button.switch-user-button:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:hover { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.13); } + .unlock-dialog .button:active, + .unlock-dialog .icon-button:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:active, + .unlock-dialog .message .message-header .message-expand-button:active, + .message .message-header .unlock-dialog .message-expand-button:active, + .unlock-dialog .message .message-header .message-close-button:active, + .message .message-header .unlock-dialog .message-close-button:active, + .unlock-dialog .screenshot-ui-show-pointer-button:active, + .unlock-dialog .login-dialog-button.cancel-button:active, + .unlock-dialog .login-dialog-button.switch-user-button:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active { + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.16); } + .unlock-dialog .button:active:hover, + .unlock-dialog .icon-button:active:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:hover, + .unlock-dialog .message .message-header .message-expand-button:active:hover, + .message .message-header .unlock-dialog .message-expand-button:active:hover, + .unlock-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .unlock-dialog .message-close-button:active:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:active:hover, + .unlock-dialog .login-dialog-button.cancel-button:active:hover, + .unlock-dialog .login-dialog-button.switch-user-button:active:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:hover { + background-color: rgba(245, 245, 245, 0.19); } + .unlock-dialog .button:active:focus, + .unlock-dialog .icon-button:active:focus, + .unlock-dialog .calendar .calendar-month-header .pager-button:active:focus, + .calendar .calendar-month-header .unlock-dialog .pager-button:active:focus, + .unlock-dialog .message .message-header .message-expand-button:active:focus, + .message .message-header .unlock-dialog .message-expand-button:active:focus, + .unlock-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .unlock-dialog .message-close-button:active:focus, + .unlock-dialog .screenshot-ui-show-pointer-button:active:focus, + .unlock-dialog .login-dialog-button.cancel-button:active:focus, + .unlock-dialog .login-dialog-button.switch-user-button:active:focus, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:active:focus { - background-color: rgba(163, 195, 234, 0.202); } ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.16), 5%); } + .unlock-dialog .button:checked, + .unlock-dialog .icon-button:checked, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked, + .unlock-dialog .message .message-header .message-expand-button:checked, + .message .message-header .unlock-dialog .message-expand-button:checked, + .unlock-dialog .message .message-header .message-close-button:checked, + .message .message-header .unlock-dialog .message-close-button:checked, + .unlock-dialog .screenshot-ui-show-pointer-button:checked, + .unlock-dialog .login-dialog-button.cancel-button:checked, + .unlock-dialog .login-dialog-button.switch-user-button:checked, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked { + color: whitesmoke; - background-color: #e1e1e1; } ++ background-color: st-darken(st-mix(whitesmoke, whitesmoke, 12%), 8%); } + .unlock-dialog .button:checked:hover, + .unlock-dialog .icon-button:checked:hover, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:hover, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:hover, + .unlock-dialog .message .message-header .message-expand-button:checked:hover, + .message .message-header .unlock-dialog .message-expand-button:checked:hover, + .unlock-dialog .message .message-header .message-close-button:checked:hover, + .message .message-header .unlock-dialog .message-close-button:checked:hover, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:hover, + .unlock-dialog .login-dialog-button.cancel-button:checked:hover, + .unlock-dialog .login-dialog-button.switch-user-button:checked:hover, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:hover { - background-color: #d6d6d6; } ++ background-color: st-darken(st-darken(st-mix(whitesmoke, whitesmoke, 12%), 8%), 4%); } + .unlock-dialog .button:checked:active, + .unlock-dialog .icon-button:checked:active, + .unlock-dialog .calendar .calendar-month-header .pager-button:checked:active, + .calendar .calendar-month-header .unlock-dialog .pager-button:checked:active, + .unlock-dialog .message .message-header .message-expand-button:checked:active, + .message .message-header .unlock-dialog .message-expand-button:checked:active, + .unlock-dialog .message .message-header .message-close-button:checked:active, + .message .message-header .unlock-dialog .message-close-button:checked:active, + .unlock-dialog .screenshot-ui-show-pointer-button:checked:active, + .unlock-dialog .login-dialog-button.cancel-button:checked:active, + .unlock-dialog .login-dialog-button.switch-user-button:checked:active, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:checked:active { - background-color: #cacaca; } ++ background-color: st-darken(st-darken(st-mix(whitesmoke, whitesmoke, 12%), 8%), 9%); } + .unlock-dialog .button:insensitive, + .unlock-dialog .icon-button:insensitive, + .unlock-dialog .calendar .calendar-month-header .pager-button:insensitive, + .calendar .calendar-month-header .unlock-dialog .pager-button:insensitive, + .unlock-dialog .message .message-header .message-expand-button:insensitive, + .message .message-header .unlock-dialog .message-expand-button:insensitive, + .unlock-dialog .message .message-header .message-close-button:insensitive, + .message .message-header .unlock-dialog .message-close-button:insensitive, + .unlock-dialog .screenshot-ui-show-pointer-button:insensitive, + .unlock-dialog .login-dialog-button.cancel-button:insensitive, + .unlock-dialog .login-dialog-button.switch-user-button:insensitive, + .unlock-dialog .login-dialog-button.login-dialog-session-list-button:insensitive { - color: rgba(245, 245, 245, 0.4); - background-color: #fdfdfd; } ++ color: st-transparentize(whitesmoke, 0.6); ++ background-color: st-lighten(st-mix(whitesmoke, whitesmoke, 12%), 3%); } + +.unlock-dialog .login-dialog-prompt-entry { + background-color: rgba(245, 245, 245, 0.1); + color: rgba(245, 245, 245, 0.7); } + .unlock-dialog .login-dialog-prompt-entry:hover { + background-color: rgba(255, 255, 255, 0.1); + color: whitesmoke; } + .unlock-dialog .login-dialog-prompt-entry:focus { - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(137, 179, 231, 0.145); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(245, 245, 245, 0.1), 5%); + color: whitesmoke; + box-shadow: inset 0 0 0 2px rgba(245, 245, 245, 0.4) !important; - background-color: rgba(245, 245, 245, 0.115); } ++ background-color: st-mix(rgba(245, 245, 245, 0.4), rgba(245, 245, 245, 0.1), 5%); } + .unlock-dialog .login-dialog-prompt-entry:insensitive { + background-color: rgba(237, 237, 237, 0.1); + color: rgba(245, 245, 245, 0.5); } + .unlock-dialog .login-dialog-prompt-entry StLabel.hint-text { + color: rgba(245, 245, 245, 0.7); } + +/* WIDGETS */ +.shell-link { - color: #1c71d8; } ++ color: st-darken(-st-accent-color, 10%); } + .shell-link:hover { - color: #418ce6; } ++ color: st-lighten(st-darken(-st-accent-color, 10%), 10%); } + +.lowres-icon { + icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } + +.icon-dropshadow { + icon-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); } + +/* Entries */ +StEntry StIcon.capslock-warning { + icon-size: 1.091em; + warning-color: #f5c211; + padding: 0 4px; } + +StEntry StIcon.peek-password { + icon-size: 1.091em; + padding: 0 4px; } + +StEntry StLabel.hint-text { + margin-left: 2px; } + +/* Buttons */ +.button { + min-height: 1.5em; } + +.icon-button, .login-dialog-button.cancel-button, .login-dialog-button.switch-user-button, .login-dialog-button.login-dialog-session-list-button, .screenshot-ui-show-pointer-button, .message .message-header .message-expand-button, +.message .message-header .message-close-button, .calendar .calendar-month-header .pager-button { + border-radius: 999px; + padding: 0.818em; + min-height: 1.091em; } + .icon-button StIcon, .login-dialog-button.cancel-button StIcon, .login-dialog-button.switch-user-button StIcon, .login-dialog-button.login-dialog-session-list-button StIcon, .screenshot-ui-show-pointer-button StIcon, .message .message-header .message-expand-button StIcon, + .message .message-header .message-close-button StIcon, .calendar .calendar-month-header .pager-button StIcon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + +/* Check Boxes */ +.check-box StBoxLayout { + spacing: .8em; } + +.check-box StBin { - width: 24px; - height: 24px; - background-image: url("resource:///org/gnome/shell/theme/checkbox-off-light.svg"); } ++ border-radius: 7px; ++ padding: 2px; } + +.check-box:focus StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused-light.svg"); } ++ background-color: rgba(0, 0, 0, 0.01); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.65); } ++ ++.check-box StIcon { ++ icon-size: 14px; ++ padding: 1px; ++ color: transparent; ++ border-radius: 6px; ++ border: 2px solid rgba(0, 0, 0, 0.15); } ++ ++.check-box:hover StIcon { ++ border-color: rgba(0, 0, 0, 0.2); } ++ ++.check-box:active StIcon { ++ border-color: rgba(0, 0, 0, 0.3); } + - .check-box:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); } ++.check-box:checked StIcon { ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; ++ border-color: transparent; } + - .check-box:focus:checked StBin { - background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); } ++.check-box:checked:hover StIcon { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } ++ ++.check-box:checked:active StIcon { ++ background-color: st-darken(-st-accent-color, 7%); ++ color: st-darken(-st-accent-fg-color, 7%); } + +/* Switches */ +.toggle-switch { - color: #282828; - height: 26px; + width: 46px; - background-size: contain; - background-image: url("resource:///org/gnome/shell/theme/toggle-off-light.svg"); } - .toggle-switch:checked { - background-image: url("resource:///org/gnome/shell/theme/toggle-on-light.svg"); } ++ border-radius: 999px; ++ transition-duration: 100ms; ++ color: #282828; ++ background: rgba(0, 0, 0, 0.15); } ++ .toggle-switch:hover { ++ background: rgba(0, 0, 0, 0.2); } + .toggle-switch StIcon { + icon-size: 16px; } ++ .toggle-switch .handle { ++ margin: 3px; ++ width: 20px; ++ height: 20px; ++ border-radius: 999px; ++ background: white; ++ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); ++ transition-duration: 100ms; } ++ .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } ++ .toggle-switch:checked .handle { ++ background: white; } + +/* Slider */ +.slider { ++ color: #282828; + -barlevel-height: 4px; - -barlevel-background-color: rgba(40, 40, 40, 0.2); - -barlevel-border-width: 2px; - -barlevel-border-color: transparent; - -barlevel-active-background-color: #1c71d8; - -barlevel-active-border-color: transparent; ++ -barlevel-background-color: rgba(40, 40, 40, 0.1); ++ -barlevel-active-background-color: -st-accent-color; + -barlevel-overdrive-color: #e01b24; - -barlevel-overdrive-border-color: transparent; + -barlevel-overdrive-separator-width: 1px; - -slider-handle-radius: 0.5455em; - -slider-handle-border-width: 0; - -slider-handle-border-color: transparent; } ++ -slider-handle-radius: 0.5455em; } ++ .slider:hover { ++ color: #3a3a3a; } + +/* Scrollbars */ +StScrollView.vfade { + -st-vfade-offset: 68px; } + +StScrollView.hfade { + -st-hfade-offset: 68px; } + +StScrollBar { + padding: 0; } + StScrollView StScrollBar { + min-width: 8px; + min-height: 8px; } + StScrollBar StBin#trough { + border-radius: 0; + background-color: transparent; } + StScrollBar StButton#vhandle, StScrollBar StButton#hhandle { + border-radius: 8px; + background-color: #b8b8b8; + border: 3px solid transparent; + transition: 500ms all ease; } + StScrollBar StButton#vhandle:hover, StScrollBar StButton#hhandle:hover { + background-color: #8f8f8f; } + StScrollBar StButton#vhandle:active, StScrollBar StButton#hhandle:active { + background-color: #a3a3a3; } + +/* Popovers/Menus */ +.popup-menu-boxpointer, .candidate-popup-boxpointer { + -arrow-rise: 6px; } + +.popup-menu { + min-width: 15em; + color: #282828; } + .popup-menu.panel-menu { + margin-bottom: 1.75em; } + +.popup-menu-content, .candidate-popup-content { + padding: 6px; + background-color: whitesmoke; + border-radius: 20px; + border: 1px solid #e3e3e3; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); } + +.popup-menu-item { + background-color: transparent; + border-color: transparent; + box-shadow: none; + border-radius: 12px; } + .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-menu-item:focus, .popup-menu-item:hover { ++ .popup-menu-item:hover { + color: #282828; - background-color: #c7c7c7; } ++ background-color: st-darken(st-mix(#282828, #e8e8e8, 12%), 4%); } + .popup-menu-item:active { + color: #282828; - background-color: #bababa; } ++ background-color: st-darken(st-mix(#282828, #e8e8e8, 12%), 9%); } + .popup-menu-item:active:hover { - background-color: #b0b0b0; } ++ background-color: st-darken(st-darken(st-mix(#282828, #e8e8e8, 12%), 9%), 4%); } + .popup-menu-item:active:focus { - background-color: #b2b6bc; } - .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, #e8e8e8, 12%), 9%), 5%); } ++ .popup-menu-item:selected, .popup-menu-item:checked { + color: #282828; - background-color: #bdbdbd; } - .popup-menu-item:checked:hover { - background-color: #b2b2b2; } - .popup-menu-item:checked:active { - background-color: #a6a6a6; } ++ background-color: st-darken(st-mix(#282828, #e8e8e8, 12%), 8%); } ++ .popup-menu-item:selected:hover, .popup-menu-item:checked:hover { ++ background-color: st-darken(st-darken(st-mix(#282828, #e8e8e8, 12%), 8%), 4%); } ++ .popup-menu-item:selected:active, .popup-menu-item:checked:active { ++ background-color: st-darken(st-darken(st-mix(#282828, #e8e8e8, 12%), 8%), 9%); } + .popup-menu-item:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: #d9d9d9; } ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(st-mix(#282828, #e8e8e8, 12%), 3%); } + .popup-menu-item:checked { + border-radius: 12px 12px 0 0 !important; } + .popup-menu-item .toggle-switch:ltr { + margin-left: 4px; } + .popup-menu-item .toggle-switch:rtl { + margin-right: 4px; } + +.popup-ornamented-menu-item:ltr { + padding-left: 6px; } + +.popup-ornamented-menu-item:rtl { + padding-right: 6px; } + +.popup-inactive-menu-item { + color: #282828; } + .popup-inactive-menu-item:insensitive { + color: #7a7a7a; } + +.popup-menu-arrow, +.popup-menu-icon { + icon-size: 1.091em; } + +.popup-sub-menu { + border-radius: 0 0 13px 13px; + margin-bottom: 6px; + border: 1px solid transparent; + background-color: #cacaca; } + .popup-sub-menu .popup-menu-item { + border-radius: 0; + border-top-width: 0; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .popup-sub-menu .popup-menu-item:insensitive { + background-color: transparent !important; } - .popup-sub-menu .popup-menu-item:focus, .popup-sub-menu .popup-menu-item:hover { ++ .popup-sub-menu .popup-menu-item:hover { + color: #282828; - background-color: #acacac; } ++ background-color: st-darken(st-mix(#282828, #cacaca, 12%), 4%); } + .popup-sub-menu .popup-menu-item:active { + color: #282828; - background-color: #9f9f9f; } ++ background-color: st-darken(st-mix(#282828, #cacaca, 12%), 9%); } + .popup-sub-menu .popup-menu-item:active:hover { - background-color: #959595; } ++ background-color: st-darken(st-darken(st-mix(#282828, #cacaca, 12%), 9%), 4%); } + .popup-sub-menu .popup-menu-item:active:focus { - background-color: #989da2; } - .popup-sub-menu .popup-menu-item:checked { ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, #cacaca, 12%), 9%), 5%); } ++ .popup-sub-menu .popup-menu-item:selected, .popup-sub-menu .popup-menu-item:checked { + color: #282828; - background-color: #a2a2a2; } - .popup-sub-menu .popup-menu-item:checked:hover { - background-color: #979797; } - .popup-sub-menu .popup-menu-item:checked:active { - background-color: #8b8b8b; } ++ background-color: st-darken(st-mix(#282828, #cacaca, 12%), 8%); } ++ .popup-sub-menu .popup-menu-item:selected:hover, .popup-sub-menu .popup-menu-item:checked:hover { ++ background-color: st-darken(st-darken(st-mix(#282828, #cacaca, 12%), 8%), 4%); } ++ .popup-sub-menu .popup-menu-item:selected:active, .popup-sub-menu .popup-menu-item:checked:active { ++ background-color: st-darken(st-darken(st-mix(#282828, #cacaca, 12%), 8%), 9%); } + .popup-sub-menu .popup-menu-item:insensitive { - color: rgba(40, 40, 40, 0.4); - background-color: #bebebe; } ++ color: st-transparentize(#282828, 0.6); ++ background-color: st-lighten(st-mix(#282828, #cacaca, 12%), 3%); } + .popup-sub-menu .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; + border-bottom-width: 0; } + .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:hover, .popup-sub-menu .popup-menu-section .popup-menu-item:last-child:focus { + border-radius: 0; } + .popup-sub-menu .popup-menu-section:last-child .popup-menu-item:last-child { + border-radius: 0 0 12px 12px; } + +.popup-menu-ornament { + icon-size: 1.091em !important; + width: 1.091em; } + +.popup-separator-menu-item { + border: none !important; } + .popup-separator-menu-item .popup-separator-menu-item-separator { + height: 1px; + background-color: rgba(40, 40, 40, 0.15); } + .popup-sub-menu .popup-separator-menu-item { + background-color: transparent; } + .popup-sub-menu .popup-separator-menu-item:ltr { + margin-right: 2.5em; } + .popup-sub-menu .popup-separator-menu-item:rtl { + margin-left: 2.5em; } + .popup-sub-menu .popup-separator-menu-item .popup-separator-menu-item-separator { + background-color: rgba(40, 40, 40, 0.15); } + +.background-menu { + -boxpointer-gap: 0px; + -arrow-rise: 0px; } + +.app-menu { + max-width: 27.25em; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:ltr { + margin-right: 8px; } + .app-menu .popup-inactive-menu-item:first-child > StLabel:rtl { + margin-left: 8px; } + +/* Date/Time Menu */ +#calendarArea { + padding: 4px; } + +.datemenu-popover { + border-radius: 30px; } + +.datemenu-calendar-column { + spacing: 6px; } + .datemenu-calendar-column:ltr { + margin-left: 6px; } + .datemenu-calendar-column:rtl { + margin-right: 6px; } + .datemenu-calendar-column .datemenu-displays-box { + spacing: 6px; } + +.datemenu-today-button { + padding: 9px; } + .datemenu-today-button .day-label { + font-weight: bold; } + +.calendar { + margin-top: 0; + padding: 0; } + .calendar .calendar-month-header .calendar-change-month-back StIcon, + .calendar .calendar-month-header .calendar-change-month-forward StIcon { + icon-size: 1.091em; } + .calendar .calendar-month-header .calendar-month-label { + color: #282828 !important; + padding: 8px 0; + width: 10em; + border-radius: 999px; + text-align: center; } + .calendar .calendar-month-header .pager-button { + height: 2.6em; + width: 2.6em; + padding: 0; } + .calendar .calendar-day { + border-radius: 999px; + height: 3em; + width: 3em; + margin: 2px; + padding: 0; + font-weight: bold; + text-align: center; } + .calendar .calendar-day.calendar-weekend { + color: #7a7a7a; } + .calendar .calendar-day.calendar-other-month { + color: rgba(40, 40, 40, 0.5); + font-weight: normal; } + .calendar .calendar-day.calendar-other-month.calendar-weekend { + color: rgba(40, 40, 40, 0.5); } + .calendar .calendar-day.calendar-today { - color: #ffffff !important; } ++ color: -st-accent-fg-color !important; } + .calendar .calendar-day.calendar-today.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today.svg") !important; } + .calendar .calendar-day.calendar-day-with-events { + background-image: url("resource:///org/gnome/shell/theme/calendar-today-light.svg"); + background-size: contain; } + .calendar .calendar-day-heading { + font-weight: bold; + text-align: center; + margin: 4px; + padding: 3px 6px; + border-radius: 8px; } + .calendar .calendar-week-number { + font-weight: bold; + font-feature-settings: "tnum"; + text-align: center; + margin: 6px; + padding: 0 6px; + border-radius: 4px; + background-color: rgba(122, 122, 122, 0.2); + color: #7a7a7a; } + +.events-button .events-box .events-title { + color: #7a7a7a; + padding-bottom: 6px; } + +.events-button .events-box .events-list { + spacing: 6px; } + .events-button .events-box .events-list .event-box { + spacing: 6px; + border-radius: 8px; } + .events-button .events-box .events-list .event-box .event-time { + color: #7a7a7a; } + .events-button .events-box .events-list .event-placeholder { + color: #7a7a7a; + font-style: italic; } + +.world-clocks-button .world-clocks-header { + color: #7a7a7a; } + .world-clocks-button .world-clocks-header.no-world-clocks { + color: #282828; } + +.world-clocks-button .world-clocks-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .world-clocks-button .world-clocks-grid .world-clocks-time { + font-weight: bold; } + .world-clocks-button .world-clocks-grid .world-clocks-time:ltr { + text-align: right; } + .world-clocks-button .world-clocks-grid .world-clocks-time:rtl { + text-align: left; } + .world-clocks-button .world-clocks-grid .world-clocks-timezone { + color: #7a7a7a; } + +.weather-button .weather-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box { + spacing: 6px; } + .weather-button .weather-box .weather-header-box .weather-header { + color: #7a7a7a; } + .weather-button .weather-box .weather-header-box .weather-header.no-location { + color: #282828; } + .weather-button .weather-box .weather-header-box .weather-header.location { + font-weight: normal; } + .weather-button .weather-box .weather-grid { + spacing-rows: 6px; + spacing-columns: 12px; } + .weather-button .weather-box .weather-grid .weather-forecast-time { + padding-top: 6px; + padding-bottom: 6px; } + .weather-button .weather-box .weather-grid .weather-forecast-icon { + icon-size: 2.182em; + margin-bottom: 4px; } + .weather-button .weather-box .weather-grid .weather-forecast-temp { + font-weight: bold; } + +/* Message List */ +.message-list { + width: 29em; + border: solid rgba(40, 40, 40, 0.15); } + .message-list:ltr { + margin-left: 0; + margin-right: 4px; + padding-right: 6px; + border-right-width: 1px; } + .message-list:rtl { + margin-right: 0; + margin-left: 4px; + padding-left: 6px; + border-left-width: 1px; } + .message-list .message-list-placeholder { + color: rgba(40, 40, 40, 0.25); } + .message-list .message-list-placeholder > StIcon { + icon-size: 96px; + margin-bottom: 12px; + -st-icon-style: symbolic; } + +.message-list-sections { + spacing: 12px; } + .message-list-sections:ltr { + margin-right: 12px; } + .message-list-sections:rtl { + margin-left: 12px; } + +.message-list-section, +.message-list-section-list { + spacing: 12px; } + +.message-list-controls { + padding: 12px; + padding-bottom: 6px; + spacing: 6px; } + .message-list-controls .dnd-button { + border-width: 2px; + border-color: transparent; + border-radius: 32px; + border-style: solid; } + .message-list-controls .dnd-button:focus { - border-color: rgba(28, 113, 216, 0.6); } ++ border-color: st-transparentize(-st-accent-color, 0.4); } + +.message { - padding: 0; ++ padding: 6px; + margin: 0; + border-radius: 16px; } - .message:ltr { - padding-right: -2px; } - .message:rtl { - padding-left: -2px; } + .message .message-header { - padding: 0 0.409em; - margin: 6px; - margin-bottom: 0; + spacing: 6px; - color: #7a7a7a; } ++ color: #7a7a7a; ++ padding: 0 6px; } ++ .message .message-header:ltr { ++ padding-right: 4px; } ++ .message .message-header:rtl { ++ padding-left: 4px; } + .message .message-header .message-source-icon { + icon-size: 1.091em; + -st-icon-style: symbolic; } + .message .message-header .message-header-content { + spacing: 6px; + min-height: 1.637em; + padding-bottom: 6px; } + .message .message-header .message-header-content .message-source-title { + font-weight: bold; } + .message .message-header .message-header-content .event-time { + color: #7a7a7a; + padding-bottom: 0.068em; } + .message .message-header .message-header-content .event-time:ltr { + text-align: right; } + .message .message-header .message-header-content .event-time:rtl { + text-align: left; } + .message .message-header .message-expand-button, + .message .message-header .message-close-button { ++ border-radius: 999px; + color: #282828; - background-color: rgba(40, 40, 40, 0.1); + padding: 4px; } - .message .message-header .message-expand-button:hover, - .message .message-header .message-close-button:hover { - background-color: rgba(40, 40, 40, 0.19); } - .message .message-header .message-expand-button:active, .message .message-header .message-expand-button:active:hover, - .message .message-header .message-close-button:active, - .message .message-header .message-close-button:active:hover { - background-color: rgba(40, 40, 40, 0.24); } - .message .message-header .message-expand-button:insensitive, - .message .message-header .message-close-button:insensitive { - background-color: rgba(40, 40, 40, 0.07); } + .message .message-header .message-expand-button { + padding: 6px; } + .message .message-header .message-expand-button:ltr { + margin-right: 6px; } + .message .message-header .message-expand-button:rtl { + margin-left: 6px; } + .message .message-box { + padding: 6px; - margin: 6px; + margin-top: 0; + spacing: 6px; } + .message .message-box .message-icon { + icon-size: 48px; } + .message .message-box .message-icon:ltr { + margin-right: 6px; } + .message .message-box .message-icon:rtl { + margin-left: 6px; } + .message .message-box .message-icon.message-themed-icon { + border-radius: 999px; + background-color: rgba(40, 40, 40, 0.07); + icon-size: 1.091em; + min-width: 48px; + min-height: 48px; } + .message .message-box:first-child { + margin-top: 12px; } + .message .message-box .message-content { + spacing: 4px; } + .message .message-box .message-content .message-title { + font-weight: bold; } ++ .message .message-action-bin { ++ padding: 4px; ++ spacing: 6px; } ++ .message .message-action-bin * { ++ margin: 0 4px; } ++ .message .message-action-bin *:first-child:ltr { ++ margin-left: 0; } ++ .message .message-action-bin *:first-child:rtl { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:ltr { ++ margin-right: 0; } ++ .message .message-action-bin *:last-child:rtl { ++ margin-left: 0; } + +.url-highlighter { - link-color: #1c71d8; } ++ link-color: st-darken(-st-accent-color, 10%); } + +/* Media Controls */ +.message-media-control { + padding: 0 18px; + border-radius: 8px; + color: #282828; + border: 1px solid transparent; } + .message-media-control:hover { + background-color: #ebebeb; + color: #282828; } + .message-media-control:active { + background-color: #e6e6e6; + color: #282828; } + .message-media-control:insensitive { + color: #878787; } + .message-media-control StIcon { + icon-size: 16px; } + +.media-message .message-icon { + border-radius: 8px !important; } + .media-message .message-icon.message-themed-icon { + icon-size: 32px !important; } + +.candidate-popup-content { + padding: 6px; + spacing: 6px; } + +.candidate-index { + padding: 0; + padding-right: 6px; + color: #7a7a7a; } + +.candidate-box { + padding: 6px 12px 6px 12px; + border-radius: 8px; } + .candidate-box:selected { - background-color: #1c71d8; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + .candidate-box:hover { + background-color: #dedede; + color: #111111; } + +.candidate-page-button-box { + height: 2em; } + .vertical .candidate-page-button-box { + padding-top: 12px; } + .horizontal .candidate-page-button-box { + padding-left: 12px; } + +.candidate-page-button { + padding: 6px; } + .candidate-page-button StIcon { + icon-size: 16px; } + +.candidate-page-button-previous { + border-radius: 8px 0px 0px 8px; + border-right-width: 0; + box-shadow: none; } + +.candidate-page-button-next { + border-radius: 0px 8px 8px 0px; + box-shadow: none; } + +/* Notifications & Message Tray */ +.notification-banner { + min-height: 64px; + width: 34em; + box-shadow: 0 2px 4px 2px rgba(0, 0, 0, 0.05); + border-radius: 16px; + margin: 4px; } + +.notification-buttons-bin { + spacing: 0; } + +/* Modal Dialogs */ +.modal-dialog { + background-color: whitesmoke; - border-radius: 16px; - box-shadow: inset 0 0 0 1px #e3e3e3; } ++ border-radius: 18px; ++ box-shadow: inset 0 0 0 1px #e3e3e3; ++ padding: 24px; } + .modal-dialog .modal-dialog-content-box { - margin: 32px 40px; + spacing: 32px; ++ margin-top: 8px; ++ margin-bottom: 16px; + max-width: 28em; } + +/* End Session Dialog */ +.end-session-dialog { - width: 30em; } ++ width: 24em; } + .end-session-dialog .end-session-dialog-battery-warning, + .end-session-dialog .dialog-list-title { + color: #f5c211; } + +/* Message Dialog */ +.message-dialog-content { + spacing: 18px; } + .message-dialog-content .message-dialog-title { + text-align: center; } + .message-dialog-content .message-dialog-description { + text-align: center; } + +/* Dialog List */ +.dialog-list { + spacing: 18px; } + .dialog-list .dialog-list-title { + text-align: center; } + .dialog-list .dialog-list-scrollview { + max-height: 200px; } + .dialog-list .dialog-list-box { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item { + spacing: 1em; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-title { + font-weight: bold; } + .dialog-list .dialog-list-box .dialog-list-item .dialog-list-item-description { + color: #1b1b1b; } + +/* Run Dialog */ +.run-dialog .modal-dialog-content-box { + margin-top: 24px; + margin-bottom: 12px; } + +.run-dialog .run-dialog-entry { + width: 20em; } + +.run-dialog .run-dialog-description { + text-align: center; + color: black; } + +/* Password or Authentication Dialog */ +.prompt-dialog { + width: 28em; } + .prompt-dialog .modal-dialog-content-box { + margin-bottom: 24px; } + +.prompt-dialog-password-grid { + spacing-rows: 8px; + spacing-columns: 4px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry { + width: auto; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:ltr { + margin-left: 20px; } + .prompt-dialog-password-grid .prompt-dialog-password-entry:rtl { + margin-right: 20px; } + +.prompt-dialog-password-layout { + spacing: 8px; } + +.prompt-dialog-password-entry { + width: 20em; } + +.prompt-dialog-error-label, +.prompt-dialog-info-label, +.prompt-dialog-null-label { + text-align: center; } + +.prompt-dialog-error-label { + color: #f5c211; } + +/* Polkit Dialog */ +.polkit-dialog-user-layout { + text-align: center; + spacing: 8px; + margin-bottom: 6px; } + .polkit-dialog-user-layout .polkit-dialog-user-root-label { + color: #f5c211; } + +/* Audio selection dialog */ +.audio-device-selection-dialog .modal-dialog-content-box { + margin-bottom: 28px; } + +.audio-device-selection-dialog .audio-selection-box { + spacing: 20px; } + +.audio-selection-device { + border-radius: 16px; } + .audio-selection-device:hover, .audio-selection-device:focus { + background-color: #dedede; } + .audio-selection-device:active { - background-color: #1c71d8; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.audio-selection-device-box { + padding: 20px; + spacing: 20px; } + +.audio-selection-device-icon { + icon-size: 64px; } + +/* Welcome dialog */ +.welcome-dialog-image { + background-image: url("resource:///org/gnome/shell/theme/gnome-shell-start.svg"); + background-size: contain; + /* Reasonable maximum dimensions */ + height: 300px; + width: 300px; } + +/* Access portal dialog */ +.access-dialog { + text-align: center; } + +/* OSD */ +.osd-window { + text-align: center; + font-weight: bold; + spacing: 12px; + padding: 12px 18px; + margin-bottom: 4em; } + .osd-window > * { + spacing: 8px; } + .osd-window StIcon { + icon-size: 32px; } + .osd-window StLabel:ltr { + margin-right: 6px; } + .osd-window StLabel:rtl { + margin-left: 6px; } + .osd-window .level { + margin-bottom: 4px; + min-width: 160px; + -barlevel-height: 6px; + -barlevel-background-color: rgba(255, 255, 255, 0.3); + -barlevel-active-background-color: #ffffff; + -barlevel-overdrive-color: #e01b24; + -barlevel-overdrive-separator-width: 3px; } + .osd-window .level:first-child { + margin-bottom: 0; } + .osd-window .level:ltr { + margin-right: 6px; } + .osd-window .level:rtl { + margin-left: 6px; } + +.osd-monitor-label { - background-color: #1c71d8; - color: #ffffff; ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; + border-radius: 16px; + font-size: 3em; + font-weight: bold; + font-feature-settings: "tnum"; + margin: 12px; + padding: 12px; + text-align: center; + min-width: 1.5em; } + +/* Pad OSD */ +.pad-osd-window { + padding: 32px; + background-color: rgba(0, 0, 0, 0.8); } + .pad-osd-window .pad-osd-title-box { + spacing: 12px; } + .pad-osd-window .pad-osd-title-menu-box { + spacing: 6px; } + +.combo-box-label { + width: 15em; } + +/* App Switcher */ +.switcher-popup { + padding: 0; + spacing: 24px; } + +.switcher-list { + padding: 12px; + border-radius: 28px; + box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.05); } + .switcher-list .switcher-list-item-container { + spacing: 12px; } + .switcher-list .item-box { + color: #ffffff; + background-color: #353535; } + .switcher-list .item-box:focus { + color: #ffffff; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(46, 69, 97, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(53, 53, 53, 0.25), 5%); } + .switcher-list .item-box:focus:hover { - background-color: #44494e; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 7%), 5%); } + .switcher-list .item-box:hover { + color: #ffffff; - background-color: #474747; } ++ background-color: st-lighten(#353535, 7%); } + .switcher-list .item-box:active { + color: #ffffff; - background-color: #4c4c4c; } ++ background-color: st-lighten(#353535, 9%); } + .switcher-list .item-box:active:hover { - background-color: #5e5e5e; } ++ background-color: st-lighten(st-lighten(#353535, 9%), 7%); } + .switcher-list .item-box:active:focus { - background-color: #494e53; } ++ background-color: st-mix(-st-accent-color, st-lighten(#353535, 9%), 5%); } + .switcher-list .item-box:highlighted, .switcher-list .item-box:selected, .switcher-list .item-box:checked { + color: #ffffff; - background-color: #494949; } ++ background-color: st-lighten(#353535, 8%); } + .switcher-list .item-box:highlighted:hover, .switcher-list .item-box:selected:hover, .switcher-list .item-box:checked:hover { - background-color: #5b5b5b; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 7%); } + .switcher-list .item-box:highlighted:active, .switcher-list .item-box:selected:active, .switcher-list .item-box:checked:active { - background-color: #606060; } ++ background-color: st-lighten(st-lighten(#353535, 8%), 9%); } + .switcher-list .item-box:insensitive { - color: rgba(255, 255, 255, 0.4); ++ color: st-transparentize(#ffffff, 0.6); + background-color: #353535; } + .switcher-list .item-box:drop { - background-color: rgba(28, 113, 216, 0.2); - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .switcher-list .item-box:hover { + background: none; } + .switcher-list .item-box:selected { + background-color: rgba(255, 255, 255, 0.2); } + .switcher-list .separator { + width: 1px; + background: rgba(40, 40, 40, 0.15); } + .switcher-list .thumbnail-box { + padding: 2px; + spacing: 6px; } + .switcher-list .thumbnail { + width: 256px; + border-radius: 8px; } + +.switcher-arrow { + border-color: rgba(255, 255, 255, 0.8); + color: rgba(255, 255, 255, 0.8); } + .switcher-arrow:highlighted { + border-color: #ffffff; + color: #ffffff; } + +.input-source-switcher-symbol { + font-size: 34pt; + width: 96px; + height: 96px; } + +.cycler-highlight { - border: 5px solid #1c71d8; } ++ border: 5px solid -st-accent-color; } + +/* Workspace Switcher */ +.workspace-switcher { + margin-bottom: 4em; + spacing: 12px; + padding: 12px 18px; } + +.ws-switcher-indicator { + background-color: rgba(255, 255, 255, 0.5); + padding: 2.6666666667px; + margin: 13.3333333333px; + border-radius: 32px; } + .ws-switcher-indicator:active { + background-color: #ffffff; + padding: 5.3333333333px; + margin: 10.6666666667px; } + +.screenshot-ui-panel { + border-radius: 32px; + padding: 18px; + padding-bottom: 12px; + margin-bottom: 4em; + spacing: 12px; } + +.screenshot-ui-close-button { + padding: 6px !important; + margin-top: 12px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); } + .screenshot-ui-close-button.left { + margin-left: 12px; } + .screenshot-ui-close-button.right { + margin-right: 12px; } + +.screenshot-ui-type-button { + min-width: 48px; + padding: 12px 18px; + border-radius: 14px; } + .screenshot-ui-type-button .icon-label-button-container { + spacing: 0.409em; } + .screenshot-ui-type-button .icon-label-button-container > StIcon { + icon-size: 32px; } + +.screenshot-ui-capture-button { + width: 32px; + height: 32px; + border-radius: 999px; + border: 4px #ffffff; + padding: 4px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle { + background-color: #ffffff; + transition-duration: 200ms; + border-radius: 999px; } + .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:hover, .screenshot-ui-capture-button .screenshot-ui-capture-button-circle:focus { + background-color: #dedede; } + .screenshot-ui-capture-button:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:focus .screenshot-ui-capture-button-circle { + background-color: #cccccc; } + .screenshot-ui-capture-button:active .screenshot-ui-capture-button-circle { + background-color: gray; } + .screenshot-ui-capture-button:cast .screenshot-ui-capture-button-circle { + background-color: #c01c28; } + .screenshot-ui-capture-button:cast:hover .screenshot-ui-capture-button-circle, .screenshot-ui-capture-button:cast:focus .screenshot-ui-capture-button-circle { + background-color: #d61f2d; } + .screenshot-ui-capture-button:cast:active .screenshot-ui-capture-button-circle { + background-color: #a11722; } + +.screenshot-ui-shot-cast-container { + background-color: rgba(255, 255, 255, 0.1); + border-radius: 999px; + padding: 3px; + spacing: 3px; } + +.screenshot-ui-shot-cast-button { + padding: 6px 12px; + background-color: transparent; + border-radius: 999px; } + .screenshot-ui-shot-cast-button > StIcon { + icon-size: 16px; } + .screenshot-ui-shot-cast-button:hover, .screenshot-ui-shot-cast-button:focus { + background-color: rgba(255, 255, 255, 0.2); } + .screenshot-ui-shot-cast-button:active { + background-color: rgba(255, 255, 255, 0.5); } + .screenshot-ui-shot-cast-button:checked { + background-color: #ffffff; + color: #353535; } + .screenshot-ui-shot-cast-button:insensitive { + color: rgba(255, 255, 255, 0.5); } + +.screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.3); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-shade { + background-color: rgba(0, 0, 0, 0.5); } + +.screenshot-ui-area-selector .screenshot-ui-area-indicator-selection { + border: 2px white; } + +.screenshot-ui-area-selector-handle { + border-radius: 999px; + background-color: white; + box-shadow: 0 1px 3px 2px rgba(0, 0, 0, 0.05); + width: 24px; + height: 24px; } + +.screenshot-ui-window-selector { + background-color: #282828; } + .screenshot-ui-window-selector .screenshot-ui-window-selector-window-container { + margin: 100px; } + .screenshot-ui-window-selector:primary-monitor .screenshot-ui-window-selector-window-container { + margin-bottom: 200px; } + +.screenshot-ui-window-selector-window-border { + transition-duration: 200ms; + border-radius: 16px; + border: 6px transparent; } + +.screenshot-ui-window-selector-check { + transition-duration: 200ms; + color: transparent; + border-radius: 999px; + border-width: 12px; + icon-size: 24px; } + +.screenshot-ui-window-selector-window:hover .screenshot-ui-window-selector-window-border { - border-color: #134e94; } ++ border-color: st-darken(-st-accent-color, 15%); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-window-border { - border-color: #1c71d8; - background-color: rgba(28, 113, 216, 0.2); } ++ border-color: -st-accent-color; ++ background-color: st-transparentize(-st-accent-color, 0.8); } + +.screenshot-ui-window-selector-window:checked .screenshot-ui-window-selector-check { - color: #ffffff; - background-color: #1c71d8; } ++ color: -st-accent-fg-color; ++ background-color: -st-accent-color; } + +.screenshot-ui-screen-selector { + transition-duration: 200ms; + background-color: rgba(0, 0, 0, 0.5); } + .screenshot-ui-screen-selector:hover { + background-color: rgba(0, 0, 0, 0.3); } + .screenshot-ui-screen-selector:active { + background-color: rgba(0, 0, 0, 0.7); } + .screenshot-ui-screen-selector:checked { + background-color: transparent; + border: 2px white; } + +.screenshot-ui-tooltip { + text-align: center; + -y-offset: 24px; } + +/* Top Bar */ +#panel { + background-color: whitesmoke; + font-weight: bold; + height: 2.2em; + transition-duration: 250ms; } + #panel .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #282828; + box-shadow: inset 0 0 0 100px transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 6px; } + #panel .panel-button:focus, #panel .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.17); } + #panel .panel-button:active, #panel .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.28); } + #panel .panel-button:active:hover, #panel .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.32); } + #panel .panel-button .system-status-icon { + icon-size: 1.091em; + padding: 0 6px; + margin: 0 4px; } + #panel .panel-button .app-menu-icon { + -st-icon-style: symbolic; } + #panel .panel-button .panel-status-menu-box, + #panel .panel-button .panel-status-indicators-box { + spacing: 4px; } + #panel .panel-button .panel-status-menu-box > .system-status-icon, + #panel .panel-button .panel-status-indicators-box > .system-status-icon { + padding: 0; } + #panel .panel-button#panelActivities StBoxLayout { + padding: 0 0.2045em; + spacing: 5px; } + #panel .panel-button#panelActivities .workspace-dot { + border-radius: 999px; + min-width: 0.5455em; + min-height: 0.5455em; + background-color: #282828; } + #panel .panel-button.screen-recording-indicator StBoxLayout, #panel .panel-button.screen-sharing-indicator StBoxLayout { + spacing: 0.409em; } + #panel .panel-button.screen-recording-indicator StIcon, #panel .panel-button.screen-sharing-indicator StIcon { + icon-size: 1.091em; } + #panel .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel .panel-button.screen-recording-indicator:focus, #panel .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #aa1923; } + #panel .panel-button.screen-recording-indicator:active, #panel .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #981620; } + #panel .panel-button.screen-recording-indicator:active:hover, #panel .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #8f151e; } + #panel .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #e66100; } + #panel .panel-button.screen-sharing-indicator:focus, #panel .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #cd5600; } + #panel .panel-button.screen-sharing-indicator:active, #panel .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #b84e00; } + #panel .panel-button.screen-sharing-indicator:active:hover, #panel .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ae4900; } + #panel .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #282828; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel .panel-button.clock-display:focus, #panel .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.17); } + #panel .panel-button.clock-display:active, #panel .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.28); } + #panel .panel-button.clock-display:active:hover, #panel .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.32); } + #panel .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel .panel-button.clock-display:focus .clock, #panel .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.17); } + #panel .panel-button.clock-display:active .clock, #panel .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.28); } + #panel .panel-button.clock-display:active .clock:hover, #panel .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(40, 40, 40, 0.32); } + #panel .panel-button.clock-display .messages-indicator { + icon-size: 1.091em; } + #panel:overview, #panel.unlock-screen, #panel.login-screen { + background-color: transparent; } + #panel:overview .panel-button.screen-recording-indicator, #panel.unlock-screen .panel-button.screen-recording-indicator, #panel.login-screen .panel-button.screen-recording-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #c01c28; } + #panel:overview .panel-button.screen-recording-indicator:focus, #panel:overview .panel-button.screen-recording-indicator:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:focus, #panel.unlock-screen .panel-button.screen-recording-indicator:hover, #panel.login-screen .panel-button.screen-recording-indicator:focus, #panel.login-screen .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px #aa1923; } + #panel:overview .panel-button.screen-recording-indicator:active, #panel:overview .panel-button.screen-recording-indicator:checked, #panel.unlock-screen .panel-button.screen-recording-indicator:active, #panel.unlock-screen .panel-button.screen-recording-indicator:checked, #panel.login-screen .panel-button.screen-recording-indicator:active, #panel.login-screen .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #981620; } + #panel:overview .panel-button.screen-recording-indicator:active:hover, #panel:overview .panel-button.screen-recording-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:active:hover, #panel.unlock-screen .panel-button.screen-recording-indicator:checked:hover, #panel.login-screen .panel-button.screen-recording-indicator:active:hover, #panel.login-screen .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #8f151e; } + #panel:overview .panel-button.screen-sharing-indicator, #panel.unlock-screen .panel-button.screen-sharing-indicator, #panel.login-screen .panel-button.screen-sharing-indicator { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px #e66100; } + #panel:overview .panel-button.screen-sharing-indicator:focus, #panel:overview .panel-button.screen-sharing-indicator:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:focus, #panel.unlock-screen .panel-button.screen-sharing-indicator:hover, #panel.login-screen .panel-button.screen-sharing-indicator:focus, #panel.login-screen .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px #cd5600; } + #panel:overview .panel-button.screen-sharing-indicator:active, #panel:overview .panel-button.screen-sharing-indicator:checked, #panel.unlock-screen .panel-button.screen-sharing-indicator:active, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked, #panel.login-screen .panel-button.screen-sharing-indicator:active, #panel.login-screen .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #b84e00; } + #panel:overview .panel-button.screen-sharing-indicator:active:hover, #panel:overview .panel-button.screen-sharing-indicator:checked:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:active:hover, #panel.unlock-screen .panel-button.screen-sharing-indicator:checked:hover, #panel.login-screen .panel-button.screen-sharing-indicator:active:hover, #panel.login-screen .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px #ae4900; } + #panel.unlock-screen .panel-button, #panel.login-screen .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; } + #panel.unlock-screen .panel-button:focus, #panel.unlock-screen .panel-button:hover, #panel.login-screen .panel-button:focus, #panel.login-screen .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button:active, #panel.unlock-screen .panel-button:checked, #panel.login-screen .panel-button:active, #panel.login-screen .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button:active:hover, #panel.unlock-screen .panel-button:checked:hover, #panel.login-screen .panel-button:active:hover, #panel.login-screen .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display, #panel.login-screen .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: #ffffff; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel.unlock-screen .panel-button.clock-display:focus, #panel.unlock-screen .panel-button.clock-display:hover, #panel.login-screen .panel-button.clock-display:focus, #panel.login-screen .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active, #panel.unlock-screen .panel-button.clock-display:checked, #panel.login-screen .panel-button.clock-display:active, #panel.login-screen .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active:hover, #panel.unlock-screen .panel-button.clock-display:checked:hover, #panel.login-screen .panel-button.clock-display:active:hover, #panel.login-screen .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel.unlock-screen .panel-button.clock-display .clock, #panel.login-screen .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel.unlock-screen .panel-button.clock-display:focus .clock, #panel.unlock-screen .panel-button.clock-display:hover .clock, #panel.login-screen .panel-button.clock-display:focus .clock, #panel.login-screen .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.17); } + #panel.unlock-screen .panel-button.clock-display:active .clock, #panel.unlock-screen .panel-button.clock-display:checked .clock, #panel.login-screen .panel-button.clock-display:active .clock, #panel.login-screen .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.28); } + #panel.unlock-screen .panel-button.clock-display:active .clock:hover, #panel.unlock-screen .panel-button.clock-display:checked .clock:hover, #panel.login-screen .panel-button.clock-display:active .clock:hover, #panel.login-screen .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(255, 255, 255, 0.32); } + #panel:overview .panel-button { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px transparent; } + #panel:overview .panel-button:focus, #panel:overview .panel-button:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button:active, #panel:overview .panel-button:checked { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button:active:hover, #panel:overview .panel-button:checked:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel:overview .panel-button#panelActivities .workspace-dot { + background-color: whitesmoke; } + #panel:overview .panel-button.clock-display { + transition-duration: 150ms; + border: 3px solid transparent; + background-color: transparent; + border-radius: 999px; + font-weight: bold; + color: whitesmoke; + box-shadow: inset 0 0 0 100px transparent; + background: none !important; + box-shadow: none !important; + border: none !important; } + #panel:overview .panel-button.clock-display:focus, #panel:overview .panel-button.clock-display:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button.clock-display:active, #panel:overview .panel-button.clock-display:checked { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button.clock-display:active:hover, #panel:overview .panel-button.clock-display:checked:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel:overview .panel-button.clock-display .clock { + transition-duration: 150ms; + border: 3px solid transparent; + border-radius: 999px; } + #panel:overview .panel-button.clock-display:focus .clock, #panel:overview .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.17); } + #panel:overview .panel-button.clock-display:active .clock, #panel:overview .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.28); } + #panel:overview .panel-button.clock-display:active .clock:hover, #panel:overview .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(245, 245, 245, 0.32); } + #panel .panel-status-indicators-box, + #panel .panel-status-menu-box { + spacing: 2px; } + #panel .power-status.panel-status-indicators-box { + spacing: 0; } + #panel .privacy-indicator { + color: #e66100; } + +#appMenu { + spacing: 0.409em; } + #appMenu .label-shadow { + color: transparent; } + +#appMenu .panel-status-menu-box { + padding: 0 0.409em; + spacing: 0.409em; } + +.clock-display-box { + spacing: 2px; } + .clock-display-box .clock { + padding-left: 0.818em; + padding-right: 0.818em; } + +/* Activities Ripple */ +.ripple-box { + background-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 0 2px 2px rgba(255, 255, 255, 0.2); + width: 52px; + height: 52px; + border-radius: 0 0 52px 0; } + .ripple-box:rtl { + border-radius: 0 0 0 52px; } + +.quick-settings { + padding: 18px; + border-radius: 36px; } + .quick-settings .icon-button, .quick-settings .login-dialog-button.cancel-button, .quick-settings .login-dialog-button.switch-user-button, .quick-settings .login-dialog-button.login-dialog-session-list-button, .quick-settings .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-settings .pager-button, .quick-settings .message .message-header .message-expand-button, .message .message-header .quick-settings .message-expand-button, + .quick-settings .message .message-header .message-close-button, + .message .message-header .quick-settings .message-close-button, .quick-settings .screenshot-ui-show-pointer-button, .quick-settings .button { + padding: 10.5px; } + +.quick-settings-grid { + spacing-rows: 12px; + spacing-columns: 12px; } + +.quick-toggle, .quick-menu-toggle { + border-radius: 999px; + min-width: 12em; + max-width: 12em; + min-height: 3.273em; + border: none; } + +.quick-toggle { + background-color: none; + /* Move padding into the box; this is to allow menu arrows + to extend to the border */ } + .quick-toggle > StBoxLayout { + spacing: 9px; } + .quick-toggle.button { + padding: 0; } + .quick-toggle > StBoxLayout { + padding: 0 12px; } + .quick-toggle:ltr > StBoxLayout { + padding-left: 15px; } + .quick-toggle:rtl > StBoxLayout { + padding-right: 15px; } + .quick-toggle .quick-toggle-title { + font-weight: bold; } + .quick-toggle StBoxLayout > .quick-toggle-subtitle { + font-weight: normal; } + .quick-toggle .quick-toggle-icon { + icon-size: 1.091em; } + +.quick-menu-toggle .quick-toggle { + min-width: auto; + max-width: auto; } + .quick-menu-toggle .quick-toggle:ltr { + border-radius: 999px 0 0 999px; } + .quick-menu-toggle .quick-toggle:ltr > StBoxLayout { + padding-right: 0.6135em; } + .quick-menu-toggle .quick-toggle:rtl { + border-radius: 0 999px 999px 0; } + .quick-menu-toggle .quick-toggle:rtr > StBoxLayout { + padding-left: 0.6135em; } + .quick-menu-toggle .quick-toggle:ltr:last-child { + border-radius: 999px; } + .quick-menu-toggle .quick-toggle:rtl:last-child { + border-radius: 999px; } + +.quick-menu-toggle .quick-toggle-arrow { + padding: 0.409em 0.71575em; + border-width: 0; + border-color: rgba(40, 40, 40, 0.25); } + .quick-menu-toggle .quick-toggle-arrow:checked { - border-color: #134e94; } ++ border-color: st-darken(-st-accent-color, 15%); } + .quick-menu-toggle .quick-toggle-arrow:ltr { + border-radius: 0 999px 999px 0; + border-left-width: 1px; } + .quick-menu-toggle .quick-toggle-arrow:rtl { + border-radius: 999px 0 0 999px; + border-right-width: 1px; } + +.quick-slider > StBoxLayout { + spacing: 6px; } + +.quick-slider .icon-button, .quick-slider .login-dialog-button.cancel-button, .quick-slider .login-dialog-button.switch-user-button, .quick-slider .login-dialog-button.login-dialog-session-list-button, .quick-slider .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .quick-slider .pager-button, .quick-slider .message .message-header .message-expand-button, .message .message-header .quick-slider .message-expand-button, +.quick-slider .message .message-header .message-close-button, +.message .message-header .quick-slider .message-close-button, .quick-slider .screenshot-ui-show-pointer-button { + padding: 6px; } + +.quick-slider .slider-bin { + padding: 6px; + border-radius: 999px; } + .quick-slider .slider-bin:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#282828, whitesmoke, 12%), 5%); } + .quick-slider .slider-bin:focus:hover { - background-color: #c9cdd2; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 4%), 5%); } + +.quick-toggle-menu { + border-radius: 24px; + margin: 12px 18px 0; } + .quick-toggle-menu:insensitive { + color: #282828; - background-color: gainsboro; } ++ background-color: st-mix(#282828, whitesmoke, 12%); } + .quick-toggle-menu .popup-menu-item > StIcon { + -st-icon-style: symbolic; + icon-size: 1.091em; } + .quick-toggle-menu .header { + spacing-rows: 3px; + spacing-columns: 12px; + padding-bottom: 12px; } + .quick-toggle-menu .header .icon { + icon-size: 1.6365em; + border-radius: 999px; + padding: 9px; + background-color: rgba(40, 40, 40, 0.2); } + .quick-toggle-menu .header .icon.active { - background-color: #1c71d8; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.quick-settings-system-item > StBoxLayout { + spacing: 12px; } + +.quick-settings-system-item .power-item { + min-height: 0; + min-width: 0; } + .quick-settings-system-item .power-item:insensitive { + color: #282828; - background-color: gainsboro; ++ background-color: st-mix(#282828, whitesmoke, 12%); + background-color: transparent; } + +.nm-network-item .wireless-secure-icon { + icon-size: 0.5455em; } + +.bt-device-item .popup-menu-icon { + -st-icon-style: symbolic; } + +.bt-menu-placeholder.popup-menu-item { + text-align: center; + padding: 2em 4em; } + +.device-subtitle { + color: rgba(40, 40, 40, 0.5); } + +.keyboard-brightness-level { + spacing: 6px; } + +.background-apps-quick-toggle { + min-height: 2.728em; + background-color: transparent; } + .background-apps-quick-toggle StIcon { + icon-size: 1.091em !important; } + +.background-app-item .popup-menu-icon { + icon-size: 32px !important; + -st-icon-style: regular !important; } + +.background-app-item .icon-button, .background-app-item .login-dialog-button.cancel-button, .background-app-item .login-dialog-button.switch-user-button, .background-app-item .login-dialog-button.login-dialog-session-list-button, .background-app-item .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .background-app-item .pager-button, .background-app-item .message .message-header .message-expand-button, .message .message-header .background-app-item .message-expand-button, +.background-app-item .message .message-header .message-close-button, +.message .message-header .background-app-item .message-close-button, .background-app-item .screenshot-ui-show-pointer-button { + padding: 6px; + background-color: rgba(40, 40, 40, 0.13); } + .background-app-item .icon-button:hover, .background-app-item .login-dialog-button.cancel-button:hover, .background-app-item .login-dialog-button.switch-user-button:hover, .background-app-item .login-dialog-button.login-dialog-session-list-button:hover, .background-app-item .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .background-app-item .pager-button:hover, .background-app-item .message .message-header .message-expand-button:hover, .message .message-header .background-app-item .message-expand-button:hover, + .background-app-item .message .message-header .message-close-button:hover, + .message .message-header .background-app-item .message-close-button:hover, .background-app-item .screenshot-ui-show-pointer-button:hover { + background-color: rgba(40, 40, 40, 0.22); } + .background-app-item .icon-button:active, .background-app-item .login-dialog-button.cancel-button:active, .background-app-item .login-dialog-button.switch-user-button:active, .background-app-item .login-dialog-button.login-dialog-session-list-button:active, .background-app-item .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .background-app-item .pager-button:active, .background-app-item .message .message-header .message-expand-button:active, .message .message-header .background-app-item .message-expand-button:active, + .background-app-item .message .message-header .message-close-button:active, + .message .message-header .background-app-item .message-close-button:active, .background-app-item .screenshot-ui-show-pointer-button:active { + background-color: rgba(40, 40, 40, 0.31); } + +.background-app-item .spinner { + padding: 6px; } + +.background-app-item.popup-inactive-menu-item { + color: #282828; } + +/* OVERVIEW */ - .controls-manager, .secondary-monitor-workspaces { ++.secondary-monitor-workspaces { + spacing: 12px; } + +#overviewGroup { + background-color: #282828; } + - .overview-controls { - padding-bottom: 32px; } - +/* Window Picker */ +.window-picker { + spacing: 6px; } + +.window-close, .screenshot-ui-close-button { + background-color: rgba(71, 71, 71, 0.98); + color: whitesmoke; + border-radius: 999px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); + padding: 3px; + height: 32px; + width: 32px; + transition-duration: 100ms; + border: 2px solid transparent; } + .window-close StIcon, .screenshot-ui-close-button StIcon { + icon-size: 24px; } + .window-close:hover, .screenshot-ui-close-button:hover { + background-color: rgba(88, 88, 88, 0.98); } + .window-close:active, .screenshot-ui-close-button:active { + background-color: rgba(104, 104, 104, 0.98); } + +.workspace-background { + border-radius: 30px; + background-color: rgba(3, 2, 1, 0); + box-shadow: 0 4px 16px 4px rgba(0, 0, 0, 0.05); } + +.search-entry { + border-radius: 999px; + margin-top: 12px; + margin-bottom: 6px; + width: 24em; } + .search-entry .search-entry-icon { + icon-size: 1.091em; + margin-top: 2px; + padding: 0 4px; } + +/* Search */ +#searchResults { + margin: 0 4px; } + +#searchResultsContent { + max-width: 1044px; } + +.search-section { + spacing: 18px; } + .search-section .search-section-separator { + height: 8px; + background-color: transparent; } + +.search-section-content { + background-color: #3d3d3d; + color: whitesmoke; + border-radius: 24px; + padding: 12px; + margin: 0 12px; + border: 2px solid transparent; } + +.list-search-result, .search-provider-icon { + color: whitesmoke; + background-color: #3d3d3d; + border-radius: 13.2px; } + .list-search-result:focus, .search-provider-icon:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(52, 75, 103, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + .list-search-result:focus:hover, .search-provider-icon:focus:hover { - background-color: #4c5156; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + .list-search-result:hover, .search-provider-icon:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .list-search-result:active, .search-provider-icon:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .list-search-result:active:hover, .search-provider-icon:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .list-search-result:active:focus, .search-provider-icon:active:focus { - background-color: #51555b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .list-search-result:highlighted, .search-provider-icon:highlighted, .list-search-result:selected, .search-provider-icon:selected, .list-search-result:checked, .search-provider-icon:checked { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + .list-search-result:highlighted:hover, .search-provider-icon:highlighted:hover, .list-search-result:selected:hover, .search-provider-icon:selected:hover, .list-search-result:checked:hover, .search-provider-icon:checked:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + .list-search-result:highlighted:active, .search-provider-icon:highlighted:active, .list-search-result:selected:active, .search-provider-icon:selected:active, .list-search-result:checked:active, .search-provider-icon:checked:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + .list-search-result:insensitive, .search-provider-icon:insensitive { - color: rgba(245, 245, 245, 0.4); ++ color: st-transparentize(whitesmoke, 0.6); + background-color: #3d3d3d; } + .list-search-result:drop, .search-provider-icon:drop { - background-color: rgba(28, 113, 216, 0.2); - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.search-statustext { + color: rgba(245, 245, 245, 0.8); } + +.grid-search-results { + spacing: 30px; } + +.search-provider-icon:ltr { + margin-right: 4px; } + +.search-provider-icon:rtl { + margin-left: 4px; } + +.search-provider-icon .list-search-provider-content { + spacing: 12px; } + .search-provider-icon .list-search-provider-content .list-search-provider-details { + width: 120px; + color: whitesmoke; } + +.list-search-results { + spacing: 6px; } + +.list-search-result .list-search-result-content { + spacing: 6px; } + +.list-search-result .list-search-result-title { + spacing: 12px; } + +.list-search-result .list-search-result-description { + color: #959595; } + +/* Dash */ +#dash { - margin-top: 12px; } ++ padding-left: 6px; ++ padding-right: 6px; } + #dash .dash-background { + background-color: #3d3d3d; + border-radius: 28px; + padding-top: 12px; + padding-bottom: 12px; + padding-left: 10px; + padding-right: 10px; } + #dash .dash-item-container .placeholder { + background-image: none; + background-size: contain; + height: 32px; } + #dash .dash-item-container .empty-dash-drop-target { + width: 32px; + height: 32px; } + #dash .dash-item-container .show-apps, + #dash .dash-item-container .overview-tile, + #dash .dash-item-container .grid-search-result { + margin: 0 2px; + padding-bottom: 12px; } + #dash .dash-item-container .show-apps .overview-icon, + #dash .dash-item-container .overview-tile .overview-icon, + #dash .dash-item-container .grid-search-result .overview-icon { + color: whitesmoke; + background-color: #3d3d3d; } + #dash .dash-item-container .show-apps:focus .overview-icon, + #dash .dash-item-container .overview-tile:focus .overview-icon, + #dash .dash-item-container .grid-search-result:focus .overview-icon { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(52, 75, 103, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + #dash .dash-item-container .show-apps:focus .overview-icon:hover, + #dash .dash-item-container .overview-tile:focus .overview-icon:hover, + #dash .dash-item-container .grid-search-result:focus .overview-icon:hover { - background-color: #4c5156; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + #dash .dash-item-container .show-apps:hover .overview-icon, + #dash .dash-item-container .overview-tile:hover .overview-icon, + #dash .dash-item-container .grid-search-result:hover .overview-icon { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + #dash .dash-item-container .show-apps:active .overview-icon, + #dash .dash-item-container .overview-tile:active .overview-icon, + #dash .dash-item-container .grid-search-result:active .overview-icon { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + #dash .dash-item-container .show-apps:active .overview-icon:hover, + #dash .dash-item-container .overview-tile:active .overview-icon:hover, + #dash .dash-item-container .grid-search-result:active .overview-icon:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + #dash .dash-item-container .show-apps:active .overview-icon:focus, + #dash .dash-item-container .overview-tile:active .overview-icon:focus, + #dash .dash-item-container .grid-search-result:active .overview-icon:focus { - background-color: #51555b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + #dash .dash-item-container .show-apps:checked .overview-icon, + #dash .dash-item-container .overview-tile:checked .overview-icon, + #dash .dash-item-container .grid-search-result:checked .overview-icon { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + #dash .dash-item-container .show-apps:checked .overview-icon:hover, + #dash .dash-item-container .overview-tile:checked .overview-icon:hover, + #dash .dash-item-container .grid-search-result:checked .overview-icon:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + #dash .dash-item-container .show-apps:checked .overview-icon:active, + #dash .dash-item-container .overview-tile:checked .overview-icon:active, + #dash .dash-item-container .grid-search-result:checked .overview-icon:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + #dash .dash-item-container .app-grid-running-dot { + offset-y: -12px; } + #dash .dash-separator { + width: 1px; + margin-left: 4px; + margin-right: 4px; + background-color: rgba(245, 245, 245, 0.1); } + #dash .dash-separator, + #dash .dash-background { + margin-bottom: 12px; } + +.dash-label { + -y-offset: 8px; } + +/* App Grid */ +.icon-grid { + row-spacing: 12px; + column-spacing: 12px; + max-row-spacing: 36px; + max-column-spacing: 36px; + page-padding-top: 24px; + page-padding-bottom: 24px; + page-padding-left: 18px; + page-padding-right: 18px; } + +/* App Icons */ +.overview-tile, .grid-search-result { + color: whitesmoke; + background-color: #282828; + border-radius: 24px; + padding: 12px; } + .overview-tile:focus, .grid-search-result:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(37, 60, 87, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.25), 5%); } + .overview-tile:focus:hover, .grid-search-result:focus:hover { - background-color: #383d42; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 7%), 5%); } + .overview-tile:hover, .grid-search-result:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .overview-tile:active, .grid-search-result:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .overview-tile:active:hover, .grid-search-result:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .overview-tile:active:focus, .grid-search-result:active:focus { - background-color: #3d4147; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + .overview-tile:highlighted, .grid-search-result:highlighted, .overview-tile:selected, .grid-search-result:selected, .overview-tile:checked, .grid-search-result:checked { + color: whitesmoke; - background-color: #3c3c3c; } ++ background-color: st-lighten(#282828, 8%); } + .overview-tile:highlighted:hover, .grid-search-result:highlighted:hover, .overview-tile:selected:hover, .grid-search-result:selected:hover, .overview-tile:checked:hover, .grid-search-result:checked:hover { - background-color: #4e4e4e; } ++ background-color: st-lighten(st-lighten(#282828, 8%), 7%); } + .overview-tile:highlighted:active, .grid-search-result:highlighted:active, .overview-tile:selected:active, .grid-search-result:selected:active, .overview-tile:checked:active, .grid-search-result:checked:active { - background-color: #535353; } ++ background-color: st-lighten(st-lighten(#282828, 8%), 9%); } + .overview-tile:insensitive, .grid-search-result:insensitive { - color: rgba(245, 245, 245, 0.4); ++ color: st-transparentize(whitesmoke, 0.6); + background-color: #282828; } + .overview-tile:drop, .grid-search-result:drop { - background-color: rgba(28, 113, 216, 0.2); - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + .overview-tile .overview-icon.overview-icon-with-label > StBoxLayout, .grid-search-result .overview-icon.overview-icon-with-label > StBoxLayout { + spacing: 6px; } + +.app-folder { + color: whitesmoke; - background-color: #414141; } ++ background-color: st-mix(whitesmoke, #282828, 12%); } + .app-folder:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #3f4349; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #282828, 12%), 5%); } + .app-folder:focus:hover { - background-color: #494d52; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 12%), 4%), 5%); } + .app-folder:hover { + color: whitesmoke; - background-color: #4b4b4b; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 12%), 4%); } + .app-folder:active { + color: whitesmoke; - background-color: #585858; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 12%), 9%); } + .app-folder:active:hover { - background-color: #626262; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 12%), 9%), 4%); } + .app-folder:active:focus { - background-color: #55595e; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 12%), 9%), 5%); } + .app-folder:highlighted, .app-folder:selected, .app-folder:checked { + color: whitesmoke; - background-color: #555555; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 12%), 8%); } + .app-folder:highlighted:hover, .app-folder:selected:hover, .app-folder:checked:hover { - background-color: #606060; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 12%), 8%), 4%); } + .app-folder:highlighted:active, .app-folder:selected:active, .app-folder:checked:active { - background-color: #6c6c6c; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 12%), 8%), 9%); } + .app-folder:insensitive { - color: rgba(245, 245, 245, 0.4); - background-color: #393939; } ++ color: st-transparentize(whitesmoke, 0.6); ++ background-color: st-darken(st-mix(whitesmoke, #282828, 12%), 3%); } + .app-folder:drop { - background-color: rgba(28, 113, 216, 0.2); - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.app-grid-running-dot { + height: 5px; + width: 5px; + border-radius: 5px; + background-color: whitesmoke; + offset-y: 6px; } + +.app-folder-dialog-container { + padding-top: 2.2em; } + +.app-folder-dialog { + width: 720px; + height: 720px; + border-radius: 64px; + background-color: #3d3d3d; + color: whitesmoke; + padding: 0 1px; + box-shadow: inset 0 0 0 1px rgba(245, 245, 245, 0.1); } + .app-folder-dialog .folder-name-container { + padding: 24px 36px; + padding-bottom: 0; } + .app-folder-dialog .folder-name-container .folder-name-entry { + width: 12em; } + .app-folder-dialog .icon-button, .app-folder-dialog .login-dialog-button.cancel-button, .app-folder-dialog .login-dialog-button.switch-user-button, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button, .app-folder-dialog .calendar .calendar-month-header .pager-button, .calendar .calendar-month-header .app-folder-dialog .pager-button, .app-folder-dialog .message .message-header .message-expand-button, .message .message-header .app-folder-dialog .message-expand-button, + .app-folder-dialog .message .message-header .message-close-button, + .message .message-header .app-folder-dialog .message-close-button, .app-folder-dialog .screenshot-ui-show-pointer-button { + color: whitesmoke; - background-color: #535353; } ++ background-color: st-mix(whitesmoke, #3d3d3d, 12%); } + .app-folder-dialog .icon-button:hover, .app-folder-dialog .login-dialog-button.cancel-button:hover, .app-folder-dialog .login-dialog-button.switch-user-button:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:hover, .app-folder-dialog .message .message-header .message-expand-button:hover, .message .message-header .app-folder-dialog .message-expand-button:hover, + .app-folder-dialog .message .message-header .message-close-button:hover, + .message .message-header .app-folder-dialog .message-close-button:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:hover { + color: whitesmoke; - background-color: #5d5d5d; } ++ background-color: st-lighten(st-mix(whitesmoke, #3d3d3d, 12%), 4%); } + .app-folder-dialog .icon-button:active, .app-folder-dialog .login-dialog-button.cancel-button:active, .app-folder-dialog .login-dialog-button.switch-user-button:active, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active, .app-folder-dialog .calendar .calendar-month-header .pager-button:active, .calendar .calendar-month-header .app-folder-dialog .pager-button:active, .app-folder-dialog .message .message-header .message-expand-button:active, .message .message-header .app-folder-dialog .message-expand-button:active, + .app-folder-dialog .message .message-header .message-close-button:active, + .message .message-header .app-folder-dialog .message-close-button:active, .app-folder-dialog .screenshot-ui-show-pointer-button:active { + color: whitesmoke; - background-color: #6a6a6a; } ++ background-color: st-lighten(st-mix(whitesmoke, #3d3d3d, 12%), 9%); } + .app-folder-dialog .icon-button:active:hover, .app-folder-dialog .login-dialog-button.cancel-button:active:hover, .app-folder-dialog .login-dialog-button.switch-user-button:active:hover, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:hover, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:hover, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:hover, .app-folder-dialog .message .message-header .message-expand-button:active:hover, .message .message-header .app-folder-dialog .message-expand-button:active:hover, + .app-folder-dialog .message .message-header .message-close-button:active:hover, + .message .message-header .app-folder-dialog .message-close-button:active:hover, .app-folder-dialog .screenshot-ui-show-pointer-button:active:hover { - background-color: #747474; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #3d3d3d, 12%), 9%), 4%); } + .app-folder-dialog .icon-button:active:focus, .app-folder-dialog .login-dialog-button.cancel-button:active:focus, .app-folder-dialog .login-dialog-button.switch-user-button:active:focus, .app-folder-dialog .login-dialog-button.login-dialog-session-list-button:active:focus, .app-folder-dialog .calendar .calendar-month-header .pager-button:active:focus, .calendar .calendar-month-header .app-folder-dialog .pager-button:active:focus, .app-folder-dialog .message .message-header .message-expand-button:active:focus, .message .message-header .app-folder-dialog .message-expand-button:active:focus, + .app-folder-dialog .message .message-header .message-close-button:active:focus, + .message .message-header .app-folder-dialog .message-close-button:active:focus, .app-folder-dialog .screenshot-ui-show-pointer-button:active:focus { - background-color: #666a6f; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #3d3d3d, 12%), 9%), 5%); } + .app-folder-dialog .page-indicators { + margin-bottom: 24px; } + .app-folder-dialog .page-navigation-arrow { + color: whitesmoke; + background-color: #3d3d3d; } + .app-folder-dialog .page-navigation-arrow:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .app-folder-dialog .page-navigation-arrow:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .app-folder-dialog .page-navigation-arrow:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .app-folder-dialog .page-navigation-arrow:active:focus { - background-color: #51555b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .app-folder-dialog .overview-tile, .app-folder-dialog .grid-search-result { + color: whitesmoke; + background-color: #3d3d3d; } + .app-folder-dialog .overview-tile:focus, .app-folder-dialog .grid-search-result:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(52, 75, 103, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(61, 61, 61, 0.25), 5%); } + .app-folder-dialog .overview-tile:focus:hover, .app-folder-dialog .grid-search-result:focus:hover { - background-color: #4c5156; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 7%), 5%); } + .app-folder-dialog .overview-tile:hover, .app-folder-dialog .grid-search-result:hover { + color: whitesmoke; - background-color: #4f4f4f; } ++ background-color: st-lighten(#3d3d3d, 7%); } + .app-folder-dialog .overview-tile:active, .app-folder-dialog .grid-search-result:active { + color: whitesmoke; - background-color: #545454; } ++ background-color: st-lighten(#3d3d3d, 9%); } + .app-folder-dialog .overview-tile:active:hover, .app-folder-dialog .grid-search-result:active:hover { - background-color: #666666; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 9%), 7%); } + .app-folder-dialog .overview-tile:active:focus, .app-folder-dialog .grid-search-result:active:focus { - background-color: #51555b; } ++ background-color: st-mix(-st-accent-color, st-lighten(#3d3d3d, 9%), 5%); } + .app-folder-dialog .overview-tile:highlighted, .app-folder-dialog .grid-search-result:highlighted, .app-folder-dialog .overview-tile:selected, .app-folder-dialog .grid-search-result:selected, .app-folder-dialog .overview-tile:checked, .app-folder-dialog .grid-search-result:checked { + color: whitesmoke; - background-color: #515151; } ++ background-color: st-lighten(#3d3d3d, 8%); } + .app-folder-dialog .overview-tile:highlighted:hover, .app-folder-dialog .grid-search-result:highlighted:hover, .app-folder-dialog .overview-tile:selected:hover, .app-folder-dialog .grid-search-result:selected:hover, .app-folder-dialog .overview-tile:checked:hover, .app-folder-dialog .grid-search-result:checked:hover { - background-color: #636363; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 7%); } + .app-folder-dialog .overview-tile:highlighted:active, .app-folder-dialog .grid-search-result:highlighted:active, .app-folder-dialog .overview-tile:selected:active, .app-folder-dialog .grid-search-result:selected:active, .app-folder-dialog .overview-tile:checked:active, .app-folder-dialog .grid-search-result:checked:active { - background-color: #686868; } ++ background-color: st-lighten(st-lighten(#3d3d3d, 8%), 9%); } + .app-folder-dialog .overview-tile:insensitive, .app-folder-dialog .grid-search-result:insensitive { - color: rgba(245, 245, 245, 0.4); ++ color: st-transparentize(whitesmoke, 0.6); + background-color: #3d3d3d; } + .app-folder-dialog .overview-tile:drop, .app-folder-dialog .grid-search-result:drop { - background-color: rgba(28, 113, 216, 0.2); - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.8); } ++ background-color: st-transparentize(-st-accent-color, 0.8); ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.2); } + +.rename-folder-popup .rename-folder-popup-item { + spacing: 6px; } + .rename-folder-popup .rename-folder-popup-item:ltr, .rename-folder-popup .rename-folder-popup-item:rtl { + padding: 0 12px; } + +.page-indicator { + padding: 6px 12px 0; + transition-duration: 400ms; } + .page-indicator .page-indicator-icon { + width: 10px; + height: 10px; + border-radius: 999px; + background-color: whitesmoke; + transition-duration: 400ms; } + +.apps-scroll-view { + padding: 0; } + +.system-action-icon { + background-color: rgba(245, 245, 245, 0.1); + color: whitesmoke; + border-radius: 999px; + icon-size: 48px; } + +.page-navigation-hint.dnd { + background: rgba(255, 255, 255, 0.1); } + +.page-navigation-hint.next:ltr, .page-navigation-hint.previous:rtl { + background-gradient-start: rgba(255, 255, 255, 0.05); + background-gradient-end: transparent; + background-gradient-direction: horizontal; + border-radius: 24px 0px 0px 24px; } + +.page-navigation-hint.previous:ltr, .page-navigation-hint.next:rtl { + background-gradient-start: transparent; + background-gradient-end: rgba(255, 255, 255, 0.05); + background-gradient-direction: horizontal; + border-radius: 0px 24px 24px 0px; } + +.page-navigation-arrow { + margin: 6px; + padding: 18px; + width: 24px; + height: 24px; + border-radius: 999px; + transition-duration: 100ms; + color: whitesmoke; + background-color: #282828; } + .page-navigation-arrow > StIcon { + color: whitesmoke; } + .page-navigation-arrow:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .page-navigation-arrow:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .page-navigation-arrow:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .page-navigation-arrow:active:focus { - background-color: #3d4147; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + +/* Workspace pager */ +.workspace-thumbnails { + visible-width: 32px; + spacing: 6px; + padding: 6px; } + .workspace-thumbnails .workspace-thumbnail { + color: whitesmoke; + background-color: #4e4e4e; + border-radius: 4px; + border: 1px solid transparent; } + .workspace-thumbnails .placeholder { + background-image: url("resource:///org/gnome/shell/theme/workspace-placeholder.svg"); + background-size: contain; + width: 18px; } + +.workspace-thumbnail-indicator { - border: 3px solid #1c71d8; ++ border: 3px solid -st-accent-color; + border-radius: 8px; } + +.ripple-pointer-location { + width: 50px; + height: 50px; + border-radius: 25px; - background-color: rgba(155, 194, 242, 0.3); - box-shadow: 0 0 2px 2px #6ea7ec; } ++ background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 30%); ++ box-shadow: 0 0 2px 2px st-lighten(-st-accent-color, 20%); } + +.pie-timer { + width: 60px; + height: 60px; + -pie-border-width: 3px; - -pie-border-color: #1c71d8; - -pie-background-color: rgba(200, 222, 248, 0.3); } ++ -pie-border-color: -st-accent-color; ++ -pie-background-color: st-lighten(st-transparentize(-st-accent-color, 0.7), 40%); } + +.magnifier-zoom-region { - border: 2px solid #1c71d8; } ++ border: 2px solid -st-accent-color; } + .magnifier-zoom-region.full-screen { + border-width: 0; } + +.select-area-rubberband { - background-color: rgba(28, 113, 216, 0.3); - border: 1px solid #1c71d8; } ++ background-color: st-transparentize(-st-accent-color, 0.7); ++ border: 1px solid -st-accent-color; } + +.user-icon { + background-size: contain; + border-radius: 999px; + icon-size: 64px; + background-color: rgba(255, 255, 255, 0.05); + color: #ffffff; } + .user-icon StIcon { + padding: 12px; } + .user-icon.user-avatar { + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); } + +.lightbox { + background-color: black; } + +.flashspot { + background-color: white; } + +.hidden { + color: transparent; } + +.caps-lock-warning-label { + text-align: center; + padding-bottom: 8px; + color: #f5c211; } + +/* Workspace animation */ +.workspace-animation { + background-color: #353535; } + +/* Tiled window previews */ +.tile-preview { - background-color: rgba(28, 113, 216, 0.5); - border: 1px solid #1c71d8; } ++ background-color: st-transparentize(-st-accent-color, 0.5); ++ border: 1px solid -st-accent-color; } + +/* On-screen Keyboard */ +#keyboard { + background-color: #353535; + box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.02); } + #keyboard .page-indicator { + padding: 6px; } + #keyboard .page-indicator .page-indicator-icon { + width: 8px; + height: 8px; } + +.key-container { + padding: 4px; + spacing: 4px; } + +.keyboard-key { + font-size: 1.455em; + font-weight: bold; + min-height: 1.2em; + min-width: 1.2em; + border-width: 1px; + border-style: solid; + border-radius: 10px; + box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05); + color: #ffffff; - background-color: #626262; } ++ background-color: st-mix(#ffffff, #4d4d4d, 12%); } + .keyboard-key:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#282828, whitesmoke, 12%), 5%); } + .keyboard-key:focus:hover { - background-color: #c9cdd2; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 4%), 5%); } + .keyboard-key:hover { + color: #ffffff; - background-color: #585858; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 4%); } + .keyboard-key:active { + color: #ffffff; - background-color: #4b4b4b; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%); } + .keyboard-key:active:hover { - background-color: #414141; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 4%); } + .keyboard-key:active:focus { - background-color: #494d52; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 5%); } + .keyboard-key:checked { + color: #ffffff; - background-color: #4e4e4e; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%); } + .keyboard-key:checked:hover { - background-color: #434343; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 4%); } + .keyboard-key:checked:active { - background-color: #373737; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 9%); } + .keyboard-key:grayed { + background-color: #ededed; + color: #ffffff; + border-color: rgba(255, 255, 255, 0.1); } + .keyboard-key.default-key { + color: #ffffff; - background-color: #494949; ++ background-color: st-mix(#ffffff, #303030, 12%); + border-radius: 10px; } + .keyboard-key.default-key:hover { + color: #ffffff; - background-color: #3f3f3f; } ++ background-color: st-darken(st-mix(#ffffff, #303030, 12%), 4%); } + .keyboard-key.default-key:active { + color: #ffffff; - background-color: #323232; } ++ background-color: st-darken(st-mix(#ffffff, #303030, 12%), 9%); } + .keyboard-key.default-key:active:hover { - background-color: #282828; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #303030, 12%), 9%), 4%); } + .keyboard-key.default-key:active:focus { - background-color: #31353a; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#ffffff, #303030, 12%), 9%), 5%); } + .keyboard-key.default-key:checked { + color: #ffffff; - background-color: #353535; } ++ background-color: st-darken(st-mix(#ffffff, #303030, 12%), 8%); } + .keyboard-key.default-key:checked:hover { - background-color: #2a2a2a; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #303030, 12%), 8%), 4%); } + .keyboard-key.default-key:checked:active { - background-color: #1e1e1e; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #303030, 12%), 8%), 9%); } + .keyboard-key.default-key:latched { - border-color: #2a7ee3; - background-color: #1c71d8; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + .keyboard-key.enter-key { - color: #ffffff; - background-color: #3782dd; ++ color: -st-accent-fg-color; ++ background-color: st-mix(-st-accent-fg-color, -st-accent-color, 12%); + border-radius: 10px; + color: #ffffff; } + .keyboard-key.enter-key:hover { - color: #ffffff; - background-color: #2677da; } ++ color: -st-accent-fg-color; ++ background-color: st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 4%); } + .keyboard-key.enter-key:active { - color: #ffffff; - background-color: #216bc5; } ++ color: -st-accent-fg-color; ++ background-color: st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 9%); } + .keyboard-key.enter-key:active:hover { - background-color: #1e62b3; } ++ background-color: st-darken(st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 9%), 4%); } + .keyboard-key.enter-key:active:focus { - background-color: #216bc6; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 9%), 5%); } + .keyboard-key.enter-key:checked { - color: #ffffff; - background-color: #226ec9; } ++ color: -st-accent-fg-color; ++ background-color: st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 8%); } + .keyboard-key.enter-key:checked:hover { - background-color: #1f64b8; } ++ background-color: st-darken(st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 8%), 4%); } + .keyboard-key.enter-key:checked:active { - background-color: #1c58a2; } ++ background-color: st-darken(st-darken(st-mix(-st-accent-fg-color, -st-accent-color, 12%), 8%), 9%); } + .keyboard-key.shift-key-uppercase { + background-color: gray; + color: #353535; } + .keyboard-key.shift-key-uppercase:hover { + background-color: #8c8c8c; + color: #424242; } + .keyboard-key StIcon { + icon-size: 24px; } + +.keyboard-subkeys { + -arrow-border-radius: 16px; + -arrow-background-color: #353535; + -arrow-border-width: 1px; + -arrow-border-color: #4c4c4c; + -arrow-base: 20px; + -arrow-rise: 10px; + -boxpointer-gap: 6px; + padding: 6px; } + .keyboard-subkeys .keyboard-key { + color: #ffffff; - background-color: #626262; ++ background-color: st-mix(#ffffff, #4d4d4d, 12%); + border-radius: 10px; } + .keyboard-subkeys .keyboard-key:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#282828, whitesmoke, 12%), 5%); } + .keyboard-subkeys .keyboard-key:focus:hover { - background-color: #c9cdd2; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 4%), 5%); } + .keyboard-subkeys .keyboard-key:hover { + color: #ffffff; - background-color: #585858; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 4%); } + .keyboard-subkeys .keyboard-key:active { + color: #ffffff; - background-color: #4b4b4b; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%); } + .keyboard-subkeys .keyboard-key:active:hover { - background-color: #414141; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 4%); } + .keyboard-subkeys .keyboard-key:active:focus { - background-color: #494d52; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 5%); } + .keyboard-subkeys .keyboard-key:checked { + color: #ffffff; - background-color: #4e4e4e; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%); } + .keyboard-subkeys .keyboard-key:checked:hover { - background-color: #434343; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 4%); } + .keyboard-subkeys .keyboard-key:checked:active { - background-color: #373737; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 9%); } + +.emoji-page .keyboard-key { + background-color: transparent; + border: none; + color: initial; } + +.emoji-panel .keyboard-key:latched { - border-color: #2a7ee3; - background-color: #1c71d8; } ++ border-color: st-lighten(-st-accent-color, 5%); ++ background-color: -st-accent-color; } + +.word-suggestions { + spacing: 12px; + min-height: 17pt; + padding: 12px; + color: #ffffff; } + .word-suggestions StButton { + margin: 0 3px; + min-width: 32px; + border-radius: 4px; + padding: 0px 18px; + background-color: transparent; + border-color: transparent; + box-shadow: none; } + .word-suggestions StButton:insensitive { + background-color: transparent !important; } + .word-suggestions StButton:focus { + color: #282828; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #d2d7dc; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(#282828, whitesmoke, 12%), 5%); } + .word-suggestions StButton:focus:hover { - background-color: #c9cdd2; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#282828, whitesmoke, 12%), 4%), 5%); } + .word-suggestions StButton:hover { + color: #ffffff; - background-color: #585858; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 4%); } + .word-suggestions StButton:active { + color: #ffffff; - background-color: #4b4b4b; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%); } + .word-suggestions StButton:active:hover { - background-color: #414141; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 4%); } + .word-suggestions StButton:active:focus { - background-color: #494d52; } ++ background-color: st-mix(-st-accent-color, st-darken(st-mix(#ffffff, #4d4d4d, 12%), 9%), 5%); } + .word-suggestions StButton:checked { + color: #ffffff; - background-color: #4e4e4e; } ++ background-color: st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%); } + .word-suggestions StButton:checked:hover { - background-color: #434343; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 4%); } + .word-suggestions StButton:checked:active { - background-color: #373737; } ++ background-color: st-darken(st-darken(st-mix(#ffffff, #4d4d4d, 12%), 8%), 9%); } + +/* Looking Glass */ ++.lg-dialog StEntry { ++ min-height: 1.5em; } ++ ++.lg-dialog .shell-link { ++ color: st-lighten(-st-accent-color, 20%); } ++ .lg-dialog .shell-link:hover { ++ color: st-lighten(st-lighten(-st-accent-color, 20%), 10%); } ++ .lg-dialog .shell-link:active { ++ color: st-darken(st-lighten(-st-accent-color, 20%), 10%); } ++ ++.lg-dialog .actor-link { ++ color: st-darken(#ffffff, 20%); } ++ .lg-dialog .actor-link:hover { ++ color: #ffffff; } ++ .lg-dialog .actor-link:active { ++ color: st-lighten(#ffffff, 20%); } ++ .lg-dialog .actor-link StIcon { ++ icon-size: 12px; } ++ ++.lg-completions-text { ++ font-style: italic; } ++ +#LookingGlassDialog { + background-color: rgba(53, 53, 53, 0.98); + color: #ffffff; + border-radius: 16px; + margin-top: 4px; + border: 2px solid transparent; + padding: 6px; + spacing: 6px; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); } + #LookingGlassDialog > #Toolbar { + border: none; + padding: 6px; + border-radius: 0; + background-color: transparent; + spacing: 6px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button { + padding: 6px 12px; } + #LookingGlassDialog > #Toolbar .lg-toolbar-button > StIcon { + icon-size: 16px; } + #LookingGlassDialog .labels { + spacing: 6px; } + #LookingGlassDialog .notebook-tab { ++ background-color: transparent; + -natural-hpadding: 12px; + -minimum-hpadding: 12px; + padding: 6px 12px; } - #LookingGlassDialog StBoxLayout#EvalBox { - padding: 4px; - spacing: 6px; - padding: 6px; } - #LookingGlassDialog StBoxLayout#ResultsArea { - spacing: 6px; - padding: 6px; } - - .lg-dialog StEntry { - min-height: 1.5em; } ++ #LookingGlassDialog .notebook-tab:selected { ++ color: #ffffff; ++ background-color: st-lighten(st-mix(#ffffff, #353535, 12%), 9%); } ++ #LookingGlassDialog .notebook-tab:selected:hover { ++ background-color: st-lighten(st-lighten(st-mix(#ffffff, #353535, 12%), 9%), 4%); } ++ #LookingGlassDialog .notebook-tab:selected:focus { ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(#ffffff, #353535, 12%), 9%), 5%); } + - .lg-dialog .shell-link { - color: #1c71d8; } - .lg-dialog .shell-link:hover { - color: #418ce6; } - .lg-dialog .shell-link:active { - color: #1659ab; } ++#LookingGlassPropertyInspector { ++ background-color: #353535; ++ color: #ffffff; ++ border-radius: 16px; ++ border: 1px solid rgba(255, 255, 255, 0.1); ++ padding: 12px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-title { ++ spacing: 4px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button, ++ #LookingGlassPropertyInspector .lg-obj-inspector-button { ++ padding: 6px 12px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button { ++ margin: 4px; ++ padding: 6px; ++ border-radius: 999px; } ++ #LookingGlassPropertyInspector .lg-obj-inspector-close-button > StIcon { ++ icon-size: 16px; } + - .lg-dialog .actor-link { - color: #7a7a7a; } - .lg-dialog .actor-link:hover { - color: #adadad; } - .lg-dialog .actor-link:active { - color: #474747; } - .lg-dialog .actor-link StIcon { - icon-size: 12px; } ++#LookingGlassEvaluator { ++ padding: 6px; } ++ #LookingGlassEvaluator .evaluator-results { ++ spacing: 6px; } + - .lg-completions-text { - font-style: italic; } ++#LookingGlassWindows { ++ padding: 6px; ++ spacing: 6px; } ++ #LookingGlassWindows .lg-window { ++ color: #ffffff; ++ background-color: st-mix(#ffffff, #353535, 12%); ++ margin: 0; ++ padding: 12px; } + - .lg-obj-inspector-title { ++#LookingGlassExtensions .lg-extensions-list { ++ padding: 6px; + spacing: 6px; } + - .lg-obj-inspector-button { - border: 1px solid rgba(40, 40, 40, 0.15); - padding: 4px; - border-radius: 8px; } - .lg-obj-inspector-button:hover { - border: 1px solid #282828; } ++#LookingGlassExtensions .lg-extension { ++ color: #ffffff; ++ background-color: st-mix(#ffffff, #353535, 12%); ++ margin: 0; ++ spacing: 4px; ++ padding: 12px; } ++ #LookingGlassExtensions .lg-extension .lg-extension-name { ++ color: #ffffff !important; } ++ #LookingGlassExtensions .lg-extension .lg-extension-meta { ++ spacing: 12px; } + - #lookingGlassExtensions { - padding: 6px; } ++#LookingGlassExtensions .lg-extensions-none { ++ color: rgba(255, 255, 255, 0.5); } + - .lg-extensions-list { ++#LookingGlassActors { + padding: 6px; - spacing: 6px; } - - .lg-extension-meta { - spacing: 6px; } ++ spacing: 4px; } + - #LookingGlassPropertyInspector { - background: whitesmoke; - border: 1px solid rgba(40, 40, 40, 0.15); - border-radius: 8px; - padding: 6px; } ++#LookingGlassDebugFlags .lg-debug-flags-header { ++ padding: 6px; ++ padding-top: 12px; } + - .lg-debug-flag-button { - color: #ffffff; } - .lg-debug-flag-button StLabel { - padding: 6px, 12px; } - .lg-debug-flag-button:hover { - color: white; } - .lg-debug-flag-button:active { - color: #cccccc; } - - .lg-debug-flags-header { - padding-top: 12px; - padding: 6px; } ++#LookingGlassDebugFlags .lg-debug-flag-button { ++ padding: 9px 12px; ++ margin-bottom: 6px; } ++ #LookingGlassDebugFlags .lg-debug-flag-button StLabel { ++ font-weight: normal !important; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch { ++ background: rgba(255, 255, 255, 0.15); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:hover { ++ background: rgba(255, 255, 255, 0.2); } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked { ++ background: -st-accent-color; ++ color: -st-accent-fg-color; } ++ #LookingGlassDebugFlags .lg-debug-flag-button .toggle-switch:checked:hover { ++ background-color: st-lighten(-st-accent-color, 5%); ++ color: st-lighten(-st-accent-fg-color, 5%); } + +.login-dialog, +.unlock-dialog { + color: whitesmoke; } + .login-dialog .caps-lock-warning-label, + .login-dialog .login-dialog-message-warning, + .unlock-dialog .caps-lock-warning-label, + .unlock-dialog .login-dialog-message-warning { + color: whitesmoke; } + .login-dialog .login-dialog-prompt-layout, + .unlock-dialog .login-dialog-prompt-layout { + width: 25em; + spacing: 9px; } + +.login-dialog-button.cancel-button { + padding: 9px; } + +.login-dialog-button-box { + spacing: 12px; } + +.conflicting-session-dialog-content { + spacing: 20px; } + .conflicting-session-dialog-content .conflicting-session-dialog-title { + text-align: center; + margin-bottom: 5px; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc { + text-align: center; } + .conflicting-session-dialog-content .conflicting-session-dialog-desc-warning { + text-align: center; + color: #f5c211; } + +.login-dialog-logo-bin { + margin: 3em 0; } + +.login-dialog-banner-view { + max-width: 25em; } + .login-dialog-banner-view .login-dialog-banner { + color: gainsboro; } + +.login-dialog-message { + text-align: center; } + +.login-dialog-message-hint, .login-dialog-message { + color: gainsboro; + min-height: 2.75em; } + +.login-dialog-user-selection-box { + padding-top: 4em; + padding-bottom: 8em; } + +.login-dialog-not-listed-label { + padding: 6px; } + +.login-dialog-not-listed-button { + color: whitesmoke; + background-color: #282828; + padding: 0 6px; + margin: 6px; } + .login-dialog-not-listed-button:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: rgba(37, 60, 87, 0.2875); } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, rgba(40, 40, 40, 0.25), 5%); } + .login-dialog-not-listed-button:focus:hover { - background-color: #383d42; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 7%), 5%); } + .login-dialog-not-listed-button:hover { + color: whitesmoke; - background-color: #3a3a3a; } ++ background-color: st-lighten(#282828, 7%); } + .login-dialog-not-listed-button:active { + color: whitesmoke; - background-color: #3f3f3f; } ++ background-color: st-lighten(#282828, 9%); } + .login-dialog-not-listed-button:active:hover { - background-color: #515151; } ++ background-color: st-lighten(st-lighten(#282828, 9%), 7%); } + .login-dialog-not-listed-button:active:focus { - background-color: #3d4147; } ++ background-color: st-mix(-st-accent-color, st-lighten(#282828, 9%), 5%); } + +.login-dialog-auth-list-view { + -st-vfade-offset: 3em; } + +.login-dialog-auth-list { + spacing: 6px; + margin-left: 2em; } + +.login-dialog-auth-list-title { + margin-left: 2em; } + +.login-dialog-auth-list-item { + border-radius: 16px; + padding: 4px; + color: darkgray; } + .login-dialog-auth-list-item:focus, .login-dialog-auth-list-item:selected { - background-color: #1c71d8; - color: #ffffff; } ++ background-color: -st-accent-color; ++ color: -st-accent-fg-color; } + +.login-dialog-auth-list-label:ltr { + padding-left: 15px; + text-align: left; } + +.login-dialog-auth-list-label:rtl { + padding-right: 15px; + text-align: right; } + +.login-dialog-user-list-view { + width: 25em; + -st-vfade-offset: 3em; } + .login-dialog-user-list-view .login-dialog-user-list { + margin: 0 8px; + spacing: 12px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item { + color: whitesmoke; - background-color: #414141; ++ background-color: st-mix(whitesmoke, #282828, 12%); + border-radius: 16px; + padding: 9px; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus { + color: whitesmoke; - box-shadow: inset 0 0 0 2px rgba(28, 113, 216, 0.5) !important; - background-color: #3f4349; } ++ box-shadow: inset 0 0 0 2px st-transparentize(-st-accent-color, 0.5) !important; ++ background-color: st-mix(-st-accent-color, st-mix(whitesmoke, #282828, 12%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:selected:hover, .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:focus:hover { - background-color: #494d52; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 12%), 4%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:hover { + color: whitesmoke; - background-color: #4b4b4b; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 12%), 4%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active { + color: whitesmoke; - background-color: #585858; } ++ background-color: st-lighten(st-mix(whitesmoke, #282828, 12%), 9%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:hover { - background-color: #626262; } ++ background-color: st-lighten(st-lighten(st-mix(whitesmoke, #282828, 12%), 9%), 4%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:active:focus { - background-color: #55595e; } ++ background-color: st-mix(-st-accent-color, st-lighten(st-mix(whitesmoke, #282828, 12%), 9%), 5%); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .user-icon { + border: 2px solid transparent; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item .login-dialog-timed-login-indicator { + height: 2px; + margin-top: 6px; + background-color: rgba(245, 245, 245, 0.7); } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon { - border-color: #1c71d8; } ++ border-color: -st-accent-color; } + .login-dialog-user-list-view .login-dialog-user-list .login-dialog-user-list-item:logged-in .user-icon StIcon { - background-color: rgba(28, 113, 216, 0.3); } ++ background-color: st-transparentize(-st-accent-color, 0.7); } + +.unlock-dialog { + background-color: transparent; } + +.screen-shield-background { + background: black; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); } + +#lockDialogGroup { + background-color: #282828; } + +.unlock-dialog-clock { + color: whitesmoke; + spacing: 2em; } + .unlock-dialog-clock .unlock-dialog-clock-time { + font-size: 6.546em; - font-weight: 200; } ++ font-weight: 800; } + .unlock-dialog-clock .unlock-dialog-clock-date { + font-weight: 400; } + .unlock-dialog-clock .unlock-dialog-clock-hint { + margin-top: 2em; + padding: 6px 18px; + border-radius: 16px; + font-weight: bold; } + +#unlockDialogNotifications StButton#vhandle, #unlockDialogNotifications StButton#hhandle { + background-color: rgba(245, 245, 245, 0.3); } + #unlockDialogNotifications StButton#vhandle:hover, #unlockDialogNotifications StButton#vhandle:focus, #unlockDialogNotifications StButton#hhandle:hover, #unlockDialogNotifications StButton#hhandle:focus { + background-color: rgba(245, 245, 245, 0.5); } + #unlockDialogNotifications StButton#vhandle:active, #unlockDialogNotifications StButton#hhandle:active { - background-color: rgba(28, 113, 216, 0.5); } ++ background-color: st-transparentize(-st-accent-color, 0.5); } + +.unlock-dialog-notifications-container { + margin: 12px; + spacing: 6px; + width: 25em; + background-color: transparent; } + .unlock-dialog-notifications-container .summary-notification-stack-scrollview { + padding-top: 0; + padding-bottom: 0; } + .unlock-dialog-notifications-container .notification, + .unlock-dialog-notifications-container .unlock-dialog-notification-source { + padding: 12px 16px; + border: none; + background-color: rgba(245, 245, 245, 0.1); + color: whitesmoke; + border-radius: 16px; } + .unlock-dialog-notifications-container .notification.critical, + .unlock-dialog-notifications-container .unlock-dialog-notification-source.critical { + background-color: rgba(245, 245, 245, 0.2); } + +.unlock-dialog-notification-icon { + icon-size: 32px; } + +.unlock-dialog-notification-label { + padding-left: 12px; + padding-right: 0; } + .unlock-dialog-notification-label:rtl { + padding-right: 12px; + padding-left: 0; } + +.unlock-dialog-notification-count-text { + font-weight: bold; + padding: 0 12px; + color: whitesmoke; + background-color: rgba(245, 245, 245, 0.1); + border-radius: 999px; } + +.login-dialog .user-widget .user-widget-label, +.unlock-dialog .user-widget .user-widget-label { + color: whitesmoke; } + +.login-dialog .user-widget .user-icon, +.unlock-dialog .user-widget .user-icon { + background-color: rgba(245, 245, 245, 0.13); + color: whitesmoke; } + +.login-dialog .user-widget.horizontal, +.unlock-dialog .user-widget.horizontal { + spacing: 18px; } + +.login-dialog .user-widget.vertical, +.unlock-dialog .user-widget.vertical { + spacing: 24px; } + .login-dialog .user-widget.vertical .user-widget-label, + .unlock-dialog .user-widget.vertical .user-widget-label { ++ font-weight: 400; ++ font-size: 1.818em; + text-align: center; + margin-bottom: .75em; } + .login-dialog .user-widget.vertical .user-icon, + .unlock-dialog .user-widget.vertical .user-icon { + icon-size: 160px; } + .login-dialog .user-widget.vertical .user-icon StIcon, + .unlock-dialog .user-widget.vertical .user-icon StIcon { - padding: 24px; } ++ padding: 30px; } diff --cc subprojects/jasmine-gjs/.eslintignore index 000000000,000000000..ccab0ca5a new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/.eslintignore @@@ -1,0 -1,0 +1,6 @@@ ++# Copied from Jasmine, use the original project's coding style ++lib/jasmine.js ++test/jasmineIntegrationTest.js ++ ++# Deliberate syntax error ++test/fixtures/syntaxErrorSpec.js diff --cc subprojects/jasmine-gjs/.eslintrc.yml index 000000000,000000000..c6ef6abc3 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/.eslintrc.yml @@@ -1,0 -1,0 +1,235 @@@ ++--- ++env: ++ es6: true ++extends: 'eslint:recommended' ++rules: ++ array-bracket-newline: ++ - error ++ - consistent ++ array-bracket-spacing: ++ - error ++ - never ++ array-callback-return: error ++ arrow-parens: ++ - error ++ - as-needed ++ arrow-spacing: error ++ block-scoped-var: error ++ block-spacing: error ++ brace-style: error ++ camelcase: ++ - error ++ - properties: never ++ allow: [^vfunc_, ^on_, _instance_init] ++ comma-dangle: ++ - error ++ - arrays: always-multiline ++ objects: always-multiline ++ functions: never ++ comma-spacing: ++ - error ++ - before: false ++ after: true ++ comma-style: ++ - error ++ - last ++ computed-property-spacing: error ++ curly: ++ - error ++ - multi-or-nest ++ - consistent ++ dot-location: ++ - error ++ - property ++ eol-last: error ++ eqeqeq: error ++ func-call-spacing: error ++ func-name-matching: error ++ func-style: ++ - error ++ - declaration ++ - allowArrowFunctions: true ++ indent: ++ - error ++ - 4 ++ - ignoredNodes: ++ # Allow not indenting the body of GObject.registerClass, since in the ++ # future it's intended to be a decorator ++ - 'CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child' ++ # Allow dedenting chained member expressions ++ MemberExpression: 'off' ++ key-spacing: ++ - error ++ - beforeColon: false ++ afterColon: true ++ keyword-spacing: ++ - error ++ - before: true ++ after: true ++ linebreak-style: ++ - error ++ - unix ++ lines-between-class-members: error ++ max-nested-callbacks: error ++ max-statements-per-line: error ++ new-parens: error ++ no-array-constructor: error ++ no-await-in-loop: error ++ no-caller: error ++ no-constant-condition: ++ - error ++ - checkLoops: false ++ no-div-regex: error ++ no-empty: ++ - error ++ - allowEmptyCatch: true ++ no-extra-bind: error ++ no-extra-parens: ++ - error ++ - all ++ - conditionalAssign: false ++ nestedBinaryExpressions: false ++ returnAssign: false ++ no-implicit-coercion: ++ - error ++ - allow: ++ - '!!' ++ no-invalid-this: error ++ no-iterator: error ++ no-label-var: error ++ no-lonely-if: error ++ no-loop-func: error ++ no-nested-ternary: error ++ no-new-object: error ++ no-new-wrappers: error ++ no-octal-escape: error ++ no-proto: error ++ no-prototype-builtins: 'off' ++ no-restricted-properties: ++ - error ++ - object: imports ++ property: format ++ message: Use template strings ++ - object: Lang ++ property: copyProperties ++ message: Use Object.assign() ++ - object: Lang ++ property: bind ++ message: Use arrow notation or Function.prototype.bind() ++ - object: Lang ++ property: Class ++ message: Use ES6 classes ++ no-restricted-syntax: ++ - error ++ - selector: >- ++ MethodDefinition[key.name="_init"] > ++ FunctionExpression[params.length=1] > ++ BlockStatement[body.length=1] ++ CallExpression[arguments.length=1][callee.object.type="Super"][callee.property.name="_init"] > ++ Identifier:first-child ++ message: _init() that only calls super._init() is unnecessary ++ - selector: >- ++ MethodDefinition[key.name="_init"] > ++ FunctionExpression[params.length=0] > ++ BlockStatement[body.length=1] ++ CallExpression[arguments.length=0][callee.object.type="Super"][callee.property.name="_init"] ++ message: _init() that only calls super._init() is unnecessary ++ - selector: BinaryExpression[operator="instanceof"][right.name="Array"] ++ message: Use Array.isArray() ++ no-return-assign: error ++ no-return-await: error ++ no-self-compare: error ++ no-shadow: error ++ no-shadow-restricted-names: error ++ no-spaced-func: error ++ no-tabs: error ++ no-template-curly-in-string: error ++ no-throw-literal: error ++ no-trailing-spaces: error ++ no-undef-init: error ++ no-unneeded-ternary: error ++ no-unused-expressions: error ++ no-unused-vars: ++ - error ++ # Vars use a suffix _ instead of a prefix because of file-scope private vars ++ - varsIgnorePattern: (^unused|_$) ++ argsIgnorePattern: ^(unused|_) ++ no-useless-call: error ++ no-useless-computed-key: error ++ no-useless-concat: error ++ no-useless-constructor: error ++ no-useless-rename: error ++ no-useless-return: error ++ no-whitespace-before-property: error ++ no-with: error ++ nonblock-statement-body-position: ++ - error ++ - below ++ object-curly-newline: ++ - error ++ - consistent: true ++ object-curly-spacing: error ++ object-shorthand: error ++ operator-assignment: error ++ operator-linebreak: error ++ prefer-const: error ++ prefer-destructuring: error ++ prefer-numeric-literals: error ++ prefer-promise-reject-errors: error ++ prefer-rest-params: error ++ prefer-spread: error ++ prefer-template: error ++ quotes: ++ - error ++ - single ++ - avoidEscape: true ++ require-await: error ++ rest-spread-spacing: error ++ semi: ++ - error ++ - always ++ semi-spacing: ++ - error ++ - before: false ++ after: true ++ semi-style: error ++ space-before-blocks: error ++ space-before-function-paren: ++ - error ++ - named: never ++ # for `function ()` and `async () =>`, preserve space around keywords ++ anonymous: always ++ asyncArrow: always ++ space-in-parens: error ++ space-infix-ops: ++ - error ++ - int32Hint: false ++ space-unary-ops: error ++ spaced-comment: error ++ switch-colon-spacing: error ++ symbol-description: error ++ template-curly-spacing: error ++ template-tag-spacing: error ++ unicode-bom: error ++ valid-jsdoc: ++ - error ++ - requireReturn: false ++ wrap-iife: ++ - error ++ - inside ++ yield-star-spacing: error ++ yoda: error ++globals: ++ ARGV: readonly ++ Debugger: readonly ++ GIRepositoryGType: readonly ++ globalThis: readonly ++ imports: readonly ++ Intl: readonly ++ log: readonly ++ logError: readonly ++ print: readonly ++ printerr: readonly ++parserOptions: ++ ecmaVersion: 2020 ++ sourceType: module diff --cc subprojects/jasmine-gjs/.jscsrc index 000000000,000000000..b796a0adb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/.jscsrc @@@ -1,0 -1,0 +1,41 @@@ ++{ ++ "disallowEmptyBlocks": true, ++ "disallowMixedSpacesAndTabs": true, ++ "disallowSpaceAfterObjectKeys": true, ++ "disallowSpaceAfterPrefixUnaryOperators": ["!", "~", "++", "--", "+", "-"], ++ "disallowSpaceBeforeBinaryOperators": [","], ++ "disallowSpacesInNamedFunctionExpression": { ++ "beforeOpeningRoundBrace": true ++ }, ++ "disallowSpacesInsideParentheses": true, ++ "disallowTrailingWhitespace": true, ++ "disallowPaddingNewlinesInBlocks": true, ++ "requireCapitalizedConstructors": true, ++ "requireCommaBeforeLineBreak": true, ++ "requireLineFeedAtFileEnd": true, ++ "requireParenthesesAroundIIFE": true, ++ "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], ++ "requireSpaceAfterKeywords": [ ++ "if", ++ "else", ++ "for", ++ "while", ++ "do", ++ "switch", ++ "return", ++ "try", ++ "catch", ++ "function" ++ ], ++ "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], ++ "requireSpaceBeforeBlockStatements": true, ++ "requireSpacesInAnonymousFunctionExpression": { ++ "beforeOpeningRoundBrace": true, ++ "beforeOpeningCurlyBrace": true ++ }, ++ "requireSpacesInFunctionDeclaration": { ++ "beforeOpeningCurlyBrace": true ++ }, ++ "validateIndentation": 4, ++ "validateLineBreaks": "LF" ++} diff --cc subprojects/jasmine-gjs/.jshintrc index 000000000,000000000..4df2414fb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/.jshintrc @@@ -1,0 -1,0 +1,33 @@@ ++{ ++ "esnext": true, ++ "evil": false, ++ "indent": 4, ++ "moz": true, ++ "multistr": true, ++ "sub": true, ++ "trailing": true, ++ "undef": true, ++ "unused": true, ++ "predef": [ ++ "addCustomEqualityTester", ++ "afterAll", ++ "afterEach", ++ "ARGV", ++ "beforeAll", ++ "beforeEach", ++ "describe", ++ "expect", ++ "fdescribe", ++ "fit", ++ "imports", ++ "it", ++ "jasmine", ++ "pending", ++ "print", ++ "printerr", ++ "spyOn", ++ "window", ++ "xdescribe", ++ "xit" ++ ] ++} diff --cc subprojects/jasmine-gjs/.travis.yml index 000000000,000000000..b3883b735 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/.travis.yml @@@ -1,0 -1,0 +1,25 @@@ ++--- ++dist: focal ++addons: ++ apt: ++ packages: ++ - gjs ++ - meson ++ - npm ++matrix: ++ include: ++ - name: Linter ++ script: | ++ npm install -g eslint && ++ eslint bin/* src test ++ - name: Unit tests ++ script: | ++ meson _build && ++ ninja -C _build && ++ RUN_THOROUGH_TESTS=yes meson test -C _build ++ - name: Installed test ++ script: | ++ meson _build && ++ ninja -C _build && ++ sudo ninja -C _build install && ++ jasmine diff --cc subprojects/jasmine-gjs/COPYING index 000000000,000000000..36a0acc3d new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/COPYING @@@ -1,0 -1,0 +1,21 @@@ ++The MIT License (MIT) ++ ++Copyright (c) 2015 Philip Chimento ++ ++Permission is hereby granted, free of charge, to any person obtaining a copy ++of this software and associated documentation files (the "Software"), to deal ++in the Software without restriction, including without limitation the rights ++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++copies of the Software, and to permit persons to whom the Software is ++furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in all ++copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++SOFTWARE. diff --cc subprojects/jasmine-gjs/NEWS.md index 000000000,000000000..ee475af86 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/NEWS.md @@@ -1,0 -1,0 +1,82 @@@ ++# Release Notes ++ ++## 2.6.4 - September 13, 2020 ++ ++- The internal copy of the Jasmine library has been updated to version 2.6.4, which brings: ++ - Add `toBeNegativeInfinity()`, `toBePositiveInfinity()`, `toHaveBeenCalledBefore()` matchers ++ - Add `spyOnProperty()` for get/set accessors ++ - Add support for ES6 sets to `toContain()` and `toEqual()` ++ - Bug fixes included in 2.6.0, 2.6.1, 2.6.2, 2.6.3 and 2.6.4 ++- Thanks to Andy Holmes for contributing. ++ ++## 2.5.2 - September 10, 2020 ++ ++- The internal copy of the Jasmine library has been updated to version 2.5.2, which brings: ++ - Add `toBeGreaterThanOrEqual()` and `toBeLessThanOrEqual()` matchers ++ - Bug fixes included in 2.5.0, 2.5.1 and 2.5.2 ++- Thanks to Andy Holmes for contributing. ++ ++## 2.4.1 - Sepetember 4, 2020 ++ ++- The internal copy of the Jasmine library has been updated to version 2.4.1, which brings: ++ - Run jasmine's specs in random order ++ - Add support for returning run details for reporting randomness ++ - Bug fixes included in 2.4.0 ++- Thanks to Andy Holmes for contributing. ++ ++## 2.3.4 - August 30, 2020 ++ ++- Fixed a regression in 2.3.0 which caused include paths in the config file to be treated as additional spec paths. ++- The TAP reporter now outputs the test plan at the beginning instead of the end, as it should. ++- The internal copy of the Jasmine library has been updated to version 2.3.4, which brings in the minor bugfixes from 2.3.1, 2.3.2, and 2.3.3 as well. ++- Thanks to Andy Holmes for contributing. ++ ++## 2.3.0 - August 25, 2020 ++ ++- Added a `--debug` command line flag which will run the tests under GDB or the debugger of your choice. ++- Added an `--interpreter` command line flag which allows using a different interpreter than whichever copy of `gjs` is in your path. ++- Fixed several bugs around the loading of spec files. ++- Improved error messages. ++- Jasmine GJS now depends on GJS 1.58.0. ++- The internal copy of the Jasmine library has been updated to 2.3.0, which brings: ++ - `done.fail()` for asynchronous specs. ++ - `toContain()` can be used for finding substrings. ++ - `toThrow()` can be used to check that a particular value was thrown. ++- Thanks to Niv Sardi, Bart Libert and Andy Holmes for contributing. ++ ++## 2.2.1 - June 30, 2015 ++ ++- We now use `/usr/bin/env` to locate jasmine-gjs which allows Jasmine to be used with a development version of GJS. (Thanks to Sam Spilsbury) ++- We don't exit with `System.exit()` on success, because that bypasses the GJS interpreter shutdown actions. (Thanks to Sam Spilsbury) ++- The internal copy of the Jasmine library has been updated to version 2.2.1, which is a minor bugfix release. ++ ++## 2.2.0 - May 17, 2015 ++ ++- You can now specify file patterns to exclude using the `--exclude` ++ command line option. ++ Previously you could only do this via the config file. ++- You can now set environment variables in the config file using the ++ `"environment"` key. ++- When you specify a directory for JUnit reports to be placed in, that ++ directory will now be created if it doesn't already exist. ++- If the argument to `--junit` is not an absolute path, then the path ++ will be resolved relative to the current directory. ++ However, you can now resolve it relative to a different path by ++ setting the environment variable `JASMINE_JUNIT_REPORTS_DIR`. ++- The verbose and TAP reporters now report the reason why a spec has ++ been marked pending, if any reason has been given. ++- The internal copy of the Jasmine library has been updated to version ++ 2.2.0, including the following features: ++ - the `toThrowError()` matcher to expect a particular exception ++ - the `jasmine.anything()` object to match anything ++ - the `jasmine.arrayContaining()` object to match an array containing ++ all of the given objects ++ - the `jasmine.stringMatching()` object to match a string that matches ++ the given regular expression or substring ++ - custom matching objects with `asymmetricMatch` methods ++ - per-spec timeouts with an extra argument to `it()`, `beforeEach()`, ++ and `afterEach()` ++ ++## 2.1.3 - March 4, 2015 ++ ++- Initial release. diff --cc subprojects/jasmine-gjs/README.md index 000000000,000000000..dfd95ed96 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/README.md @@@ -1,0 -1,0 +1,232 @@@ ++[![Build Status](https://travis-ci.org/ptomato/jasmine-gjs.png?branch=master)](https://travis-ci.org/ptomato/jasmine-gjs) ++ ++# Jasmine for GJS ++ ++[Jasmine](https://github.com/jasmine/jasmine) is a BDD (behavior-driven ++development) framework for JavaScript. ++ ++## Contents ++ ++This module allows you to run Jasmine specs for your GJS code. ++The output will be displayed in your terminal. ++ ++## Installation ++ ++From Git: ++ ++```sh ++git clone https://github.com/ptomato/jasmine-gjs ++cd jasmine-gjs ++meson _build ++ninja -C _build ++sudo ninja -C _build install ++``` ++ ++From a tarball: ++ ++```sh ++tar xJf jasmine-gjs-2.1.3.tar.xz ++cd jasmine-gjs-2.1.3 ++meson _build ++ninja -C _build ++sudo ninja -C _build install ++``` ++ ++## Usage ++ ++To run your test suite, pass its directory to the `jasmine` command: ++ ++```bash ++jasmine mytestsuitedir ++``` ++ ++To run an individual spec: ++ ++```bash ++jasmine path/to/spec.js ++``` ++ ++## Options ++ ++`--no-color`: Don't output color in the terminal. ++(Opposite of `--color`.) ++ ++`--exclude `: Don't run specs that match `file` (which may ++contain `?` and `*` wildcards.) ++This is useful if you pass a directory of specs that also contains ++utility modules or specs that you don't want to run by default. ++You may specify this option more than once with different arguments. ++ ++`--verbose`: Output verbose results, formatted similarly to Mocha's ++output. ++(The default output is formatted the same as Jasmine's Node.JS runner's ++output.) ++ ++`--tap`: Output according to the ++[Test Anything Protocol](http://testanything.org/). ++This is useful when integrating with Automake (see below.) ++ ++`--junit []`: In addition to the console output, print a JUnit-style ++XML report to `file`. ++If no file is given, the default is `report.xml` in the current working ++directory. ++If you don't specify an absolute path but you do set the environment variable `JASMINE_JUNIT_REPORTS_DIR`, then the report will be placed there instead. ++This allows you to use `$$tst` as the argument to `--junit` in your Makefile to mirror your test directory structure in your report directory. ++ ++`--config `: Use `file` as Jasmine's configuration file instead of ++the default `jasmine.json`. ++ ++`--no-config`: Don't load a configuration file, even if one is present. ++ ++## Configuration file ++ ++Maybe you don't want to keep typing the same options every time you run ++your tests. ++In that case, you can create a configuration file called `jasmine.json`. ++Jasmine will look for it in the current working directory by default. ++ ++If you configure your test suites in the configuration file, then you ++can start Jasmine simply by running ++ ++```bash ++jasmine ++``` ++ ++The file should be a JSON file. ++You can use the following keys: ++ ++`include_paths`: (string or array of strings) ++Prepend these paths to GJS's include paths, in order of priority, ++highest first. ++(The same as specifying `-I` to GJS or defining the `GJS_PATH` ++environment variable.) ++Relative paths are resolved relative to the configuration file's ++location. ++ ++`options`: (string or array of strings) ++Use these command-line options for Jasmine by default. ++Options given on the command line will override these in the event of a ++conflict. ++ ++`exclude`: (string or array of strings) ++Don't run specs in these files or directories. ++They may contain `*` and `?` as wildcards. ++(The same as specifying `--exclude` on the command line.) ++ ++`spec_files`: (string or array of strings) ++Run specs in these files or directories. ++The same as specifying files or directories on the command line. ++If you specify any on the command line, then this option is entirely ++ignored; this is useful for running your entire test suite by default ++but retaining the ability to run just one spec file on the command line. ++Relative paths are resolved relative to the configuration file's ++location. ++ ++`environment`: (object with string properties) ++Execute specs with a modified environment. ++Each property of the given object is added as an environment variable. ++If a property's value is `null`, then any existing environment variable ++of that name is unset. ++This is mainly useful if your Javascript code uses a private C library; ++you can add `LD_LIBRARY_PATH` and `GI_TYPELIB_PATH` to `environment` in ++order to expose that library to GJS's GObject introspection repository. ++ ++## Integration with Meson ++ ++If using Meson, you might want to integrate your test suite into your build process. ++Meson can parse the output of the TAP reporter automatically and display a full report at the end. ++ ++Put this code in `meson.build`: ++ ++``` ++jasmine = find_program('jasmine') ++ ++test(test_name, jasmine, args: [test_file, '--tap', '--no-config'], ++ protocol: 'tap') ++``` ++ ++Where `test_name` and `test_file` are the name of your test and the JS ++script to run, respectively. ++ ++## Integration with Autotools ++ ++If using autotools, you might want to integrate your test suite into ++your makefiles. ++The TAP reporter produces output that Automake can parse and display ++while the tests are running. ++That way, you have more immediate feedback and can see problems directly ++from your build output. ++ ++Put this code in `configure.ac`: ++ ++``` ++AC_PROG_AWK ++AC_REQUIRE_AUX_FILE([tap-driver.sh]) ++``` ++ ++Then re-run `autogen.sh` or `autoreconf` to install the TAP driver. ++ ++Then, put this code in your `Makefile.am`: ++ ++```make ++JS_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh ++JS_LOG_DRIVER_FLAGS = --comments ++ ++TESTS = path/to/spec1.js path/to/spec2.js ++TEST_EXTENSIONS = .js ++JS_LOG_COMPILER = jasmine ++AM_JS_LOG_FLAGS = --tap --no-config ++``` ++ ++Don't forget to `EXTRA_DIST` your spec files too. ++Now Jasmine will run your spec files one by one as part of `make check`. ++ ++With this configuration, the TAP driver displays all the extra ++diagnostic information about suites starting and finishing, and ++expectation messages in case of failure. ++If you don't want that, remove the `JS_LOG_DRIVER_FLAGS` line. ++ ++### A note on extra files ++ ++If you use on-disk test fixtures, you should note that someone may be ++building your software with separate source and build trees. ++Notably, Meson does this. ++In that case, you have to make sure that your fixtures can be found both ++when running tests from the source directory and from a separate build ++directory. ++I suggest defining an environment variable in your makefile that tells ++where the fixtures can be found. ++For example, in Jasmine GJS's own tests, this line is in `meson.build`: ++ ++``` ++test_env = { ++ 'SRCDIR': meson.current_source_dir(), ++} ++``` ++ ++The test code then reads the environment variable like this: ++ ++```js ++let envSrcdir = GLib.getenv('SRCDIR'); ++const SRCDIR = envSrcdir? envSrcdir + '/' : ''; ++ ++doSomethingWithFixture(SRCDIR + 'path/to/fixture'); ++``` ++ ++## Support ++ ++Please file issues here at ++[GitHub](https://github.com/ptomato/jasmine-gjs/issues). ++ ++## Credits ++ ++The idea of Jasmine for GJS was first explored by my coworkers Devin ++Ekins and Sam Spilsbury: ++[eos-jasmine](https://github.com/endlessm/eos-jasmine). ++This code, however, was unashamedly cribbed from Pivotal Labs' ++[jasmine-npm](https://github.com/jasmine/jasmine-npm), then expanded ++into what it is now. ++ ++Copyright (c) 2015 Philip Chimento. ++This software is licensed under the MIT License — because Jasmine ++and Jasmine NPM are too. diff --cc subprojects/jasmine-gjs/bin/jasmine-runner.in index 000000000,000000000..b2f2bb11c new file mode 100755 --- /dev/null +++ b/subprojects/jasmine-gjs/bin/jasmine-runner.in @@@ -1,0 -1,0 +1,34 @@@ ++#!/usr/bin/env -S gjs -m ++ ++/* global jasmineImporter */ ++ ++import GLib from 'gi://GLib'; ++ ++const pkgdatadir = GLib.getenv('TEST_PKGDATADIR') ?? '@pkgdatadir@'; ++const jasmineMod = GLib.getenv('TEST_JASMINE_MOD') ?? '@jasmine_mod@'; ++ ++// Create a separate GJS importer object for Jasmine modules, so that Jasmine's ++// modules are not exposed to test code (e.g. client code might have its own ++// Utils module.) ++// This means that all imports within Jasmine must use jasmineImporter rather ++// than imports. That includes imports of Jasmine modules in the tests. It would ++// be better to test a separate copy of Jasmine code, but importing most modules ++// registers a GType, and we cannot register two GTypes with the same name in ++// the same process. ++ ++const oldSearchPath = imports.searchPath.slice(); // make a copy ++imports.searchPath.unshift(GLib.path_get_dirname(pkgdatadir)); ++globalThis.jasmineImporter = imports[jasmineMod]; ++imports.searchPath = oldSearchPath; ++ ++const base = `file://${pkgdatadir}`; ++ ++const Command = await import(`${base}/command.js`); ++const JasmineBoot = await import(`${base}/jasmineBoot.js`); ++ ++// Do not conflict with global "jasmine" object ++const _jasmine = new JasmineBoot.Jasmine(); ++_jasmine.installAPI(globalThis); ++ ++// Don't put any code after this; the return value is used as the exit code. ++await Command.run(_jasmine, ARGV, 10); diff --cc subprojects/jasmine-gjs/bin/jasmine.in index 000000000,000000000..ee5769257 new file mode 100755 --- /dev/null +++ b/subprojects/jasmine-gjs/bin/jasmine.in @@@ -1,0 -1,0 +1,37 @@@ ++#!/usr/bin/env -S gjs -m ++ ++import GLib from 'gi://GLib'; ++import * as System from 'system'; ++ ++const pkglibexecdir = GLib.getenv('TEST_PKGLIBEXECDIR') ?? '@pkglibexecdir@'; ++const pkgdatadir = GLib.getenv('TEST_PKGDATADIR') ?? '@pkgdatadir@'; ++ ++const runnerPath = `${pkglibexecdir}/jasmine-runner`; ++const base = `file://${pkgdatadir}`; ++ ++const Config = await import(`${base}/config.js`); ++const Options = await import(`${base}/options.js`); ++ ++const [files, options] = Options.parseOptions(ARGV); ++ ++if (options.version) { ++ print('Jasmine @PACKAGE_VERSION@'); ++ System.exit(0); ++} ++ ++const config = Config.loadConfig(options); ++ ++// Launch Jasmine in a subprocess so we can control the environment ++const launcher = Config.prepareLauncher(config, options); ++let args = Config.configToArgs(config, files, options); ++args.unshift(runnerPath); // argv[0] ++args = Config.wrapArgs(args, config, options); ++const process = launcher.spawnv(args); ++process.wait(null); ++ ++// Don't put any code after this; the return value is used as the exit code. ++(function () { ++ if (process.get_if_exited()) ++ return process.get_exit_status(); ++ return 1; ++})(); diff --cc subprojects/jasmine-gjs/debian/changelog index 000000000,000000000..02e243e9b new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/changelog @@@ -1,0 -1,0 +1,52 @@@ ++jasmine-gjs (2.6.4-1) unstable; urgency=low ++ ++ * Upgrade to 2.6.4 ++ ++ -- Andy Holmes Thu, 10 Sep 2020 21:47:34 -0700 ++ ++jasmine-gjs (2.5.2-1) unstable; urgency=low ++ ++ * Upgrade to 2.5.2 ++ ++ -- Andy Holmes Fri, 04 Sep 2020 19:20:51 -0700 ++ ++jasmine-gjs (2.4.1-1) unstable; urgency=low ++ ++ * Upgrade to 2.4.1 ++ ++ -- Andy Holmes Sat, 29 Aug 2020 19:46:28 -0700 ++ ++jasmine-gjs (2.3.4-1) unstable; urgency=low ++ ++ * Upgrade to 2.3.4 ++ ++ -- Andy Holmes Wed, 26 Aug 2020 16:34:43 -0700 ++ ++jasmine-gjs (2.3.0-1) unstable; urgency=low ++ ++ * Upgrade to 2.3.0 ++ * control: Bump GJS requirement to 1.58.0 ++ * control, rules: Meson build system ++ * control: Update to modern versions of standards and debhelper-compat ++ ++ -- Philip Chimento Tue, 25 Aug 2020 22:19:41 -0700 ++ ++jasmine-gjs (2.2.1-1) unstable; urgency=low ++ ++ * Upgrade to 2.2.1 ++ ++ -- Philip Chimento Tue, 30 Jun 2015 14:24:39 -0700 ++ ++jasmine-gjs (2.2.0-1) unstable; urgency=low ++ ++ * Upgrade to 2.2.0 ++ * copyright: Update copyright year of upstream Jasmine ++ * docs: Add new NEWS.md file ++ ++ -- Philip Chimento Mon, 18 May 2015 01:03:37 -0700 ++ ++jasmine-gjs (2.1.3-1) unstable; urgency=low ++ ++ * Initial release ++ ++ -- Philip Chimento Sun, 01 Mar 2015 15:25:17 -0800 diff --cc subprojects/jasmine-gjs/debian/control index 000000000,000000000..117ba70d9 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/control @@@ -1,0 -1,0 +1,19 @@@ ++Source: jasmine-gjs ++Section: devel ++Priority: optional ++Maintainer: Philip Chimento ++Build-Depends: debhelper-compat (= 12), ++ gir1.2-glib-2.0, ++ gjs (>= 1.58.0), ++ meson (>= 0.50.0) ++Standards-Version: 4.5.0 ++Homepage: https://github.com/ptomato/jasmine-gjs ++ ++Package: jasmine-gjs ++Architecture: all ++Depends: ${misc:Depends}, ++ gir1.2-glib-2.0, ++ gjs (>= 1.58.0) ++Description: Behavior-driven development framework for GJS ++ This module allows you to run Jasmine specs for your GJS code. The output will ++ be displayed in your terminal. diff --cc subprojects/jasmine-gjs/debian/copyright index 000000000,000000000..d61cab19c new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/copyright @@@ -1,0 -1,0 +1,31 @@@ ++Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ ++Upstream-Name: jasmine-gjs ++Source: https://github.com/ptomato/jasmine-gjs ++License: Expat ++ ++Files: * ++Copyright: 2015 Philip Chimento ++License: Expat ++ ++Files: lib/jasmine.js ++Copyright: 2008-2015 Pivotal Labs ++License: Expat ++ ++License: Expat ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ . ++ The above copyright notice and this permission notice shall be included in all ++ copies or substantial portions of the Software. ++ . ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ SOFTWARE. diff --cc subprojects/jasmine-gjs/debian/docs index 000000000,000000000..dc676dd5a new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/docs @@@ -1,0 -1,0 +1,2 @@@ ++README.md ++NEWS.md diff --cc subprojects/jasmine-gjs/debian/rules index 000000000,000000000..5897036ba new file mode 100755 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/rules @@@ -1,0 -1,0 +1,12 @@@ ++#!/usr/bin/make -f ++# -*- makefile -*- ++ ++# Uncomment this to turn on verbose mode. ++#export DH_VERBOSE=1 ++ ++%: ++ dh $@ ++ ++# Print out test log on failure, so that we can diagnose failures on OBS ++override_dh_auto_test: ++ dh_auto_test || (find . -name testlog.txt | xargs cat ; exit 1) diff --cc subprojects/jasmine-gjs/debian/source/format index 000000000,000000000..163aaf8d8 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/debian/source/format @@@ -1,0 -1,0 +1,1 @@@ ++3.0 (quilt) diff --cc subprojects/jasmine-gjs/jasmine-gjs.spec index 000000000,000000000..352b2e974 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/jasmine-gjs.spec @@@ -1,0 -1,0 +1,64 @@@ ++Name: jasmine-gjs ++Version: 2.6.4 ++Release: 1%{?dist} ++Summary: A behavior-driven development framework for GJS ++ ++License: MIT ++URL: https://github.com/ptomato/jasmine-gjs ++Source0: http://ptomato.name/downloads/jasmine-gjs-2.6.4.tar.xz ++ ++BuildArch: noarch ++BuildRequires: gjs >= 1.58.0 ++BuildRequires: gobject-introspection ++BuildRequires: meson >= 0.50.0 ++Requires: gjs >= 1.58.0 ++Requires: gobject-introspection ++ ++%description ++This module allows you to run Jasmine specs for your GJS code. The output will ++be displayed in your terminal. ++ ++%prep ++%autosetup ++ ++ ++%build ++%meson ++%meson_build ++ ++ ++%install ++%meson_install ++ ++ ++%check ++%meson_test ++ ++ ++%files ++%doc README.md ++%doc NEWS.md ++%doc COPYING ++%doc %{_mandir}/man1/jasmine.1.gz ++%{_bindir}/jasmine ++%{_libexecdir}/%{name}/ ++%{_datadir}/%{name}/ ++ ++ ++%changelog ++* Fri Sep 10 2020 Andy Holmes - 2.6.4-1 ++- Update to version 2.6.4. ++* Fri Sep 4 2020 Andy Holmes - 2.5.2-1 ++- Update to version 2.5.2. ++* Sat Aug 29 2020 Andy Holmes - 2.4.1-1 ++- Update to version 2.4.1. ++* Wed Aug 26 2020 Andy Holmes - 2.3.4-1 ++- Update to version 2.3.4. ++* Mon Aug 24 2020 Philip Chimento - 2.3.0-1 ++- Update to version 2.3.0. ++* Tue Jun 30 2015 Philip Chimento - 2.2.1-1 ++- Update to version 2.2.1. ++* Sun May 17 2015 Philip Chimento - 2.2.0-1 ++- Update to version 2.2.0. ++* Wed Mar 4 2015 Philip Chimento - 2.1.3-1 ++- Initial packaging. diff --cc subprojects/jasmine-gjs/jasmine.json index 000000000,000000000..550ff263e new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/jasmine.json @@@ -1,0 -1,0 +1,5 @@@ ++{ ++ "exclude": ["test/fixtures/*", "test/focusedSpecIntegrationTest.js"], ++ "spec_files": "test", ++ "options": "--verbose" ++} diff --cc subprojects/jasmine-gjs/jasmine.man index 000000000,000000000..16f298071 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/jasmine.man @@@ -1,0 -1,0 +1,107 @@@ ++.\" Copyright 2015 Philip Chimento ++.TH JASMINE 1 "March 1, 2015" ++.\" Please adjust this date whenever revising the manpage. ++.SH NAME ++jasmine \- run Jasmine test suites ++.SH SYNOPSIS ++.B jasmine ++.RB [ \-\-help ] ++.RB [ \-\-color ] ++.RB [ \-\-no\-color ] ++.RB [ \-\-config ++.IR file ] ++.RB [ \-\-no\-config ] ++.RB [ \-\-exclude ++.IR file ] ++.RB [ \-\-verbose ] ++.RB [ \-\-tap ] ++.RB [ \-\-junit ++.RI [ file "]] " files " ..." ++.SH DESCRIPTION ++Jasmine is a behavior-driven development framework for the GJS Javascript ++interpreter. ++The ++.B jasmine ++command is a test runner for Jasmine test suites that has several different ++output formats. ++.PP ++The ++.I files ++specified on the command line are imported and all Jasmine specs defined therein ++are executed. ++You may also specify whole directories in ++.IR files , ++in which case the directories are searched recursively and files ending in ++.I .js ++will be imported. ++.SH OPTIONS ++.TP ++.B \-\-color ++Print output in color, if the chosen output format supports it. ++.TP ++.BI \-\-config " file" ++Use ++.I file ++as the configuration file, instead of ++.IR jasmine.json . ++.TP ++.BI \-\-exclude " file" ++Don't execute specs in ++.I file ++(which may also be a wildcard pattern) even if they are in a directory specified ++on the command line. ++(Don't forget to escape wildcards so the shell doesn't expand them.) ++.TP ++.B \-\-help ++Show summary of options. ++.TP ++.BI \-\-junit " file" ++In addition to the format used to report results to the console (default, ++.BR \-\-verbose , ++or ++.BR \-\-tap ,) ++output test results to a JUnit-style XML file to ++.IR file , ++suitable for integration with Jenkins. ++If ++.I file ++is not given, output to ++.I report.xml ++in the current directory. ++.TP ++.B \-\-no\-color ++Do not print output in color, even if the chosen output format supports it. ++.TP ++.B \-\-no\-config ++Don't use a configuration file, even if one is present. ++.TP ++.B \-\-tap ++Report results with the TAP (Test Anything Protocol) reporter, suitable for ++integration with Automake. ++.TP ++.B \-\-verbose ++Report results with the verbose reporter, similar to Mocha's default reporter. ++.SH EXIT STATUS ++The ++.B jasmine ++utility exits with 0 on success, or with 1 if any tests failed or an internal ++error occurred. ++.SH ENVIRONMENT ++The JASMINE_JUNIT_REPORTS_DIR environment variable controls where JUnit-style ++XML reports are placed, if a relative path is passed to ++.B \-\-junit ++on the command line. ++.PP ++The JASMINE_UNINSTALLED environment variable can be used for debugging Jasmine. ++It is not recommended to set this variable during normal use. ++.SH FILES ++By default, Jasmine reads from a configuration file called ++.I jasmine.json ++in the current directory, if such a file exists. ++This can be influenced with the ++.B \-\-config ++and ++.B \-\-no\-config ++options. ++.SH BUGS ++Report bugs at https://github.com/ptomato/jasmine-gjs/issues on GitHub. diff --cc subprojects/jasmine-gjs/lib/jasmine.js index 000000000,000000000..007712b25 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/lib/jasmine.js @@@ -1,0 -1,0 +1,10116 @@@ ++/* jscs:disable */ ++/* ++Copyright (c) 2008-2021 Pivotal Labs ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice shall be ++included in all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++*/ ++// eslint-disable-next-line no-unused-vars ++var getJasmineRequireObj = (function(jasmineGlobal) { ++ var jasmineRequire; ++ ++ if ( ++ typeof module !== 'undefined' && ++ module.exports && ++ typeof exports !== 'undefined' ++ ) { ++ if (typeof global !== 'undefined') { ++ jasmineGlobal = global; ++ } else { ++ jasmineGlobal = {}; ++ } ++ jasmineRequire = exports; ++ } else { ++ if ( ++ typeof window !== 'undefined' && ++ typeof window.toString === 'function' && ++ window.toString() === '[object GjsGlobal]' ++ ) { ++ jasmineGlobal = window; ++ } ++ jasmineRequire = jasmineGlobal.jasmineRequire = {}; ++ } ++ ++ function getJasmineRequire() { ++ return jasmineRequire; ++ } ++ ++ getJasmineRequire().core = function(jRequire) { ++ var j$ = {}; ++ ++ jRequire.base(j$, jasmineGlobal); ++ j$.util = jRequire.util(j$); ++ j$.errors = jRequire.errors(); ++ j$.formatErrorMsg = jRequire.formatErrorMsg(); ++ j$.Any = jRequire.Any(j$); ++ j$.Anything = jRequire.Anything(j$); ++ j$.CallTracker = jRequire.CallTracker(j$); ++ j$.MockDate = jRequire.MockDate(); ++ j$.getClearStack = jRequire.clearStack(j$); ++ j$.Clock = jRequire.Clock(); ++ j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$); ++ j$.Env = jRequire.Env(j$); ++ j$.StackTrace = jRequire.StackTrace(j$); ++ j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$); ++ j$.ExpectationFilterChain = jRequire.ExpectationFilterChain(); ++ j$.Expector = jRequire.Expector(j$); ++ j$.Expectation = jRequire.Expectation(j$); ++ j$.buildExpectationResult = jRequire.buildExpectationResult(j$); ++ j$.JsApiReporter = jRequire.JsApiReporter(j$); ++ j$.asymmetricEqualityTesterArgCompatShim = jRequire.asymmetricEqualityTesterArgCompatShim( ++ j$ ++ ); ++ j$.makePrettyPrinter = jRequire.makePrettyPrinter(j$); ++ j$.pp = j$.makePrettyPrinter(); ++ j$.MatchersUtil = jRequire.MatchersUtil(j$); ++ j$.matchersUtil = new j$.MatchersUtil({ ++ customTesters: [], ++ pp: j$.pp ++ }); ++ ++ j$.ObjectContaining = jRequire.ObjectContaining(j$); ++ j$.ArrayContaining = jRequire.ArrayContaining(j$); ++ j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$); ++ j$.MapContaining = jRequire.MapContaining(j$); ++ j$.SetContaining = jRequire.SetContaining(j$); ++ j$.QueueRunner = jRequire.QueueRunner(j$); ++ j$.ReportDispatcher = jRequire.ReportDispatcher(j$); ++ j$.Spec = jRequire.Spec(j$); ++ j$.Spy = jRequire.Spy(j$); ++ j$.SpyFactory = jRequire.SpyFactory(j$); ++ j$.SpyRegistry = jRequire.SpyRegistry(j$); ++ j$.SpyStrategy = jRequire.SpyStrategy(j$); ++ j$.StringMatching = jRequire.StringMatching(j$); ++ j$.StringContaining = jRequire.StringContaining(j$); ++ j$.UserContext = jRequire.UserContext(j$); ++ j$.Suite = jRequire.Suite(j$); ++ j$.Timer = jRequire.Timer(); ++ j$.TreeProcessor = jRequire.TreeProcessor(); ++ j$.version = jRequire.version(); ++ j$.Order = jRequire.Order(); ++ j$.DiffBuilder = jRequire.DiffBuilder(j$); ++ j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$); ++ j$.ObjectPath = jRequire.ObjectPath(j$); ++ j$.MismatchTree = jRequire.MismatchTree(j$); ++ j$.GlobalErrors = jRequire.GlobalErrors(j$); ++ ++ j$.Truthy = jRequire.Truthy(j$); ++ j$.Falsy = jRequire.Falsy(j$); ++ j$.Empty = jRequire.Empty(j$); ++ j$.NotEmpty = jRequire.NotEmpty(j$); ++ ++ j$.matchers = jRequire.requireMatchers(jRequire, j$); ++ j$.asyncMatchers = jRequire.requireAsyncMatchers(jRequire, j$); ++ ++ return j$; ++ }; ++ ++ return getJasmineRequire; ++})(this); ++ ++getJasmineRequireObj().requireMatchers = function(jRequire, j$) { ++ var availableMatchers = [ ++ 'nothing', ++ 'toBe', ++ 'toBeCloseTo', ++ 'toBeDefined', ++ 'toBeInstanceOf', ++ 'toBeFalse', ++ 'toBeFalsy', ++ 'toBeGreaterThan', ++ 'toBeGreaterThanOrEqual', ++ 'toBeLessThan', ++ 'toBeLessThanOrEqual', ++ 'toBeNaN', ++ 'toBeNegativeInfinity', ++ 'toBeNull', ++ 'toBePositiveInfinity', ++ 'toBeTrue', ++ 'toBeTruthy', ++ 'toBeUndefined', ++ 'toContain', ++ 'toEqual', ++ 'toHaveSize', ++ 'toHaveBeenCalled', ++ 'toHaveBeenCalledBefore', ++ 'toHaveBeenCalledOnceWith', ++ 'toHaveBeenCalledTimes', ++ 'toHaveBeenCalledWith', ++ 'toHaveClass', ++ 'toMatch', ++ 'toThrow', ++ 'toThrowError', ++ 'toThrowMatching' ++ ], ++ matchers = {}; ++ ++ for (var i = 0; i < availableMatchers.length; i++) { ++ var name = availableMatchers[i]; ++ matchers[name] = jRequire[name](j$); ++ } ++ ++ return matchers; ++}; ++ ++getJasmineRequireObj().base = function(j$, jasmineGlobal) { ++ j$.unimplementedMethod_ = function() { ++ throw new Error('unimplemented method'); ++ }; ++ ++ /** ++ * Maximum object depth the pretty printer will print to. ++ * Set this to a lower value to speed up pretty printing if you have large objects. ++ * @name jasmine.MAX_PRETTY_PRINT_DEPTH ++ * @default 8 ++ * @since 1.3.0 ++ */ ++ j$.MAX_PRETTY_PRINT_DEPTH = 8; ++ /** ++ * Maximum number of array elements to display when pretty printing objects. ++ * This will also limit the number of keys and values displayed for an object. ++ * Elements past this number will be ellipised. ++ * @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH ++ * @default 50 ++ * @since 2.7.0 ++ */ ++ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50; ++ /** ++ * Maximum number of characters to display when pretty printing objects. ++ * Characters past this number will be ellipised. ++ * @name jasmine.MAX_PRETTY_PRINT_CHARS ++ * @default 100 ++ * @since 2.9.0 ++ */ ++ j$.MAX_PRETTY_PRINT_CHARS = 1000; ++ /** ++ * Default number of milliseconds Jasmine will wait for an asynchronous spec, ++ * before, or after function to complete. This can be overridden on a case by ++ * case basis by passing a time limit as the third argument to {@link it}, ++ * {@link beforeEach}, {@link afterEach}, {@link beforeAll}, or ++ * {@link afterAll}. The value must be no greater than the largest number of ++ * milliseconds supported by setTimeout, which is usually 2147483647. ++ * ++ * While debugging tests, you may want to set this to a large number (or pass ++ * a large number to one of the functions mentioned above) so that Jasmine ++ * does not move on to after functions or the next spec while you're debugging. ++ * @name jasmine.DEFAULT_TIMEOUT_INTERVAL ++ * @default 5000 ++ * @since 1.3.0 ++ */ ++ var DEFAULT_TIMEOUT_INTERVAL = 5000; ++ Object.defineProperty(j$, 'DEFAULT_TIMEOUT_INTERVAL', { ++ get: function() { ++ return DEFAULT_TIMEOUT_INTERVAL; ++ }, ++ set: function(newValue) { ++ j$.util.validateTimeout(newValue, 'jasmine.DEFAULT_TIMEOUT_INTERVAL'); ++ DEFAULT_TIMEOUT_INTERVAL = newValue; ++ } ++ }); ++ ++ j$.getGlobal = function() { ++ return jasmineGlobal; ++ }; ++ ++ /** ++ * Get the currently booted Jasmine Environment. ++ * ++ * @name jasmine.getEnv ++ * @since 1.3.0 ++ * @function ++ * @return {Env} ++ */ ++ j$.getEnv = function(options) { ++ var env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options)); ++ //jasmine. singletons in here (setTimeout blah blah). ++ return env; ++ }; ++ ++ j$.isArray_ = function(value) { ++ return j$.isA_('Array', value); ++ }; ++ ++ j$.isObject_ = function(value) { ++ return ( ++ !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value) ++ ); ++ }; ++ ++ j$.isString_ = function(value) { ++ return j$.isA_('String', value); ++ }; ++ ++ j$.isNumber_ = function(value) { ++ return j$.isA_('Number', value); ++ }; ++ ++ j$.isFunction_ = function(value) { ++ return j$.isA_('Function', value); ++ }; ++ ++ j$.isAsyncFunction_ = function(value) { ++ return j$.isA_('AsyncFunction', value); ++ }; ++ ++ j$.isGeneratorFunction_ = function(value) { ++ return j$.isA_('GeneratorFunction', value); ++ }; ++ ++ j$.isTypedArray_ = function(value) { ++ return ( ++ j$.isA_('Float32Array', value) || ++ j$.isA_('Float64Array', value) || ++ j$.isA_('Int16Array', value) || ++ j$.isA_('Int32Array', value) || ++ j$.isA_('Int8Array', value) || ++ j$.isA_('Uint16Array', value) || ++ j$.isA_('Uint32Array', value) || ++ j$.isA_('Uint8Array', value) || ++ j$.isA_('Uint8ClampedArray', value) ++ ); ++ }; ++ ++ j$.isA_ = function(typeName, value) { ++ return j$.getType_(value) === '[object ' + typeName + ']'; ++ }; ++ ++ j$.isError_ = function(value) { ++ if (!value) { ++ return false; ++ } ++ ++ if (value instanceof Error) { ++ return true; ++ } ++ if ( ++ typeof window !== 'undefined' && ++ typeof window.trustedTypes !== 'undefined' ++ ) { ++ return ( ++ typeof value.stack === 'string' && typeof value.message === 'string' ++ ); ++ } ++ if (value && value.constructor && value.constructor.constructor) { ++ var valueGlobal = value.constructor.constructor('return this'); ++ if (j$.isFunction_(valueGlobal)) { ++ valueGlobal = valueGlobal(); ++ } ++ ++ if (valueGlobal.Error && value instanceof valueGlobal.Error) { ++ return true; ++ } ++ } ++ return false; ++ }; ++ ++ j$.isAsymmetricEqualityTester_ = function(obj) { ++ return obj?.asymmetricMatch ? j$.isA_('Function', obj.asymmetricMatch) : false; ++ }; ++ ++ j$.getType_ = function(value) { ++ return Object.prototype.toString.apply(value); ++ }; ++ ++ j$.isDomNode = function(obj) { ++ // Node is a function, because constructors ++ return typeof jasmineGlobal.Node !== 'undefined' ++ ? obj instanceof jasmineGlobal.Node ++ : obj !== null && ++ typeof obj === 'object' && ++ typeof obj.nodeType === 'number' && ++ typeof obj.nodeName === 'string'; ++ // return obj.nodeType > 0; ++ }; ++ ++ j$.isMap = function(obj) { ++ return ( ++ obj !== null && ++ typeof obj !== 'undefined' && ++ typeof jasmineGlobal.Map !== 'undefined' && ++ obj.constructor === jasmineGlobal.Map ++ ); ++ }; ++ ++ j$.isSet = function(obj) { ++ return ( ++ obj !== null && ++ typeof obj !== 'undefined' && ++ typeof jasmineGlobal.Set !== 'undefined' && ++ obj.constructor === jasmineGlobal.Set ++ ); ++ }; ++ ++ j$.isWeakMap = function(obj) { ++ return ( ++ obj !== null && ++ typeof obj !== 'undefined' && ++ typeof jasmineGlobal.WeakMap !== 'undefined' && ++ obj.constructor === jasmineGlobal.WeakMap ++ ); ++ }; ++ ++ j$.isURL = function(obj) { ++ return ( ++ obj !== null && ++ typeof obj !== 'undefined' && ++ typeof jasmineGlobal.URL !== 'undefined' && ++ obj.constructor === jasmineGlobal.URL ++ ); ++ }; ++ ++ j$.isDataView = function(obj) { ++ return ( ++ obj !== null && ++ typeof obj !== 'undefined' && ++ typeof jasmineGlobal.DataView !== 'undefined' && ++ obj.constructor === jasmineGlobal.DataView ++ ); ++ }; ++ ++ j$.isPromise = function(obj) { ++ return ( ++ typeof jasmineGlobal.Promise !== 'undefined' && ++ !!obj && ++ obj.constructor === jasmineGlobal.Promise ++ ); ++ }; ++ ++ j$.isPromiseLike = function(obj) { ++ return !!obj && j$.isFunction_(obj.then); ++ }; ++ ++ j$.fnNameFor = function(func) { ++ if (func.name) { ++ return func.name; ++ } ++ ++ var matches = ++ func.toString().match(/^\s*function\s*(\w+)\s*\(/) || ++ func.toString().match(/^\s*\[object\s*(\w+)Constructor\]/); ++ ++ return matches ? matches[1] : ''; ++ }; ++ ++ j$.isPending_ = function(promise) { ++ var sentinel = {}; ++ // eslint-disable-next-line compat/compat ++ return Promise.race([promise, Promise.resolve(sentinel)]).then( ++ function(result) { ++ return result === sentinel; ++ }, ++ function() { ++ return false; ++ } ++ ); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is an instance of the specified class/constructor. ++ * @name jasmine.any ++ * @since 1.3.0 ++ * @function ++ * @param {Constructor} clazz - The constructor to check against. ++ */ ++ j$.any = function(clazz) { ++ return new j$.Any(clazz); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is not `null` and not `undefined`. ++ * @name jasmine.anything ++ * @since 2.2.0 ++ * @function ++ */ ++ j$.anything = function() { ++ return new j$.Anything(); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is `true` or anything truthy. ++ * @name jasmine.truthy ++ * @since 3.1.0 ++ * @function ++ */ ++ j$.truthy = function() { ++ return new j$.Truthy(); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is `null`, `undefined`, `0`, `false` or anything falsey. ++ * @name jasmine.falsy ++ * @since 3.1.0 ++ * @function ++ */ ++ j$.falsy = function() { ++ return new j$.Falsy(); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is empty. ++ * @name jasmine.empty ++ * @since 3.1.0 ++ * @function ++ */ ++ j$.empty = function() { ++ return new j$.Empty(); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared is not empty. ++ * @name jasmine.notEmpty ++ * @since 3.1.0 ++ * @function ++ */ ++ j$.notEmpty = function() { ++ return new j$.NotEmpty(); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value being compared contains at least the keys and values. ++ * @name jasmine.objectContaining ++ * @since 1.3.0 ++ * @function ++ * @param {Object} sample - The subset of properties that _must_ be in the actual. ++ */ ++ j$.objectContaining = function(sample) { ++ return new j$.ObjectContaining(sample); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value is a `String` that matches the `RegExp` or `String`. ++ * @name jasmine.stringMatching ++ * @since 2.2.0 ++ * @function ++ * @param {RegExp|String} expected ++ */ ++ j$.stringMatching = function(expected) { ++ return new j$.StringMatching(expected); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value is a `String` that contains the specified `String`. ++ * @name jasmine.stringContaining ++ * @since 3.10.0 ++ * @function ++ * @param {String} expected ++ */ ++ j$.stringContaining = function(expected) { ++ return new j$.StringContaining(expected); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value is an `Array` that contains at least the elements in the sample. ++ * @name jasmine.arrayContaining ++ * @since 2.2.0 ++ * @function ++ * @param {Array} sample ++ */ ++ j$.arrayContaining = function(sample) { ++ return new j$.ArrayContaining(sample); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if the actual value is an `Array` that contains all of the elements in the sample in any order. ++ * @name jasmine.arrayWithExactContents ++ * @since 2.8.0 ++ * @function ++ * @param {Array} sample ++ */ ++ j$.arrayWithExactContents = function(sample) { ++ return new j$.ArrayWithExactContents(sample); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if every key/value pair in the sample passes the deep equality comparison ++ * with at least one key/value pair in the actual value being compared ++ * @name jasmine.mapContaining ++ * @since 3.5.0 ++ * @function ++ * @param {Map} sample - The subset of items that _must_ be in the actual. ++ */ ++ j$.mapContaining = function(sample) { ++ return new j$.MapContaining(sample); ++ }; ++ ++ /** ++ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), ++ * that will succeed if every item in the sample passes the deep equality comparison ++ * with at least one item in the actual value being compared ++ * @name jasmine.setContaining ++ * @since 3.5.0 ++ * @function ++ * @param {Set} sample - The subset of items that _must_ be in the actual. ++ */ ++ j$.setContaining = function(sample) { ++ return new j$.SetContaining(sample); ++ }; ++ ++ /** ++ * Determines whether the provided function is a Jasmine spy. ++ * @name jasmine.isSpy ++ * @since 2.0.0 ++ * @function ++ * @param {Function} putativeSpy - The function to check. ++ * @return {Boolean} ++ */ ++ j$.isSpy = function(putativeSpy) { ++ if (!putativeSpy || !putativeSpy.and) { ++ return false; ++ } ++ return ( ++ putativeSpy.and instanceof j$.SpyStrategy && ++ putativeSpy.calls instanceof j$.CallTracker ++ ); ++ }; ++}; ++ ++getJasmineRequireObj().util = function(j$) { ++ var util = {}; ++ ++ util.inherit = function(childClass, parentClass) { ++ var Subclass = function() {}; ++ Subclass.prototype = parentClass.prototype; ++ childClass.prototype = new Subclass(); ++ }; ++ ++ util.argsToArray = function(args) { ++ var arrayOfArgs = []; ++ for (var i = 0; i < args.length; i++) { ++ arrayOfArgs.push(args[i]); ++ } ++ return arrayOfArgs; ++ }; ++ ++ util.isUndefined = function(obj) { ++ return obj === void 0; ++ }; ++ ++ util.arrayContains = function(array, search) { ++ var i = array.length; ++ while (i--) { ++ if (array[i] === search) { ++ return true; ++ } ++ } ++ return false; ++ }; ++ ++ util.clone = function(obj) { ++ if (Object.prototype.toString.apply(obj) === '[object Array]') { ++ return obj.slice(); ++ } ++ ++ var cloned = {}; ++ for (var prop in obj) { ++ if (obj.hasOwnProperty(prop)) { ++ cloned[prop] = obj[prop]; ++ } ++ } ++ ++ return cloned; ++ }; ++ ++ util.cloneArgs = function(args) { ++ var clonedArgs = []; ++ var argsAsArray = j$.util.argsToArray(args); ++ for (var i = 0; i < argsAsArray.length; i++) { ++ var str = Object.prototype.toString.apply(argsAsArray[i]), ++ primitives = /^\[object (Boolean|String|RegExp|Number)/; ++ ++ // All falsey values are either primitives, `null`, or `undefined. ++ if (!argsAsArray[i] || str.match(primitives)) { ++ clonedArgs.push(argsAsArray[i]); ++ } else { ++ clonedArgs.push(j$.util.clone(argsAsArray[i])); ++ } ++ } ++ return clonedArgs; ++ }; ++ ++ util.getPropertyDescriptor = function(obj, methodName) { ++ var descriptor, ++ proto = obj; ++ ++ do { ++ descriptor = Object.getOwnPropertyDescriptor(proto, methodName); ++ proto = Object.getPrototypeOf(proto); ++ } while (!descriptor && proto); ++ ++ return descriptor; ++ }; ++ ++ util.objectDifference = function(obj, toRemove) { ++ var diff = {}; ++ ++ for (var key in obj) { ++ if (util.has(obj, key) && !util.has(toRemove, key)) { ++ diff[key] = obj[key]; ++ } ++ } ++ ++ return diff; ++ }; ++ ++ util.has = function(obj, key) { ++ return Object.prototype.hasOwnProperty.call(obj, key); ++ }; ++ ++ util.errorWithStack = function errorWithStack() { ++ // Don't throw and catch if we don't have to, because it makes it harder ++ // for users to debug their code with exception breakpoints. ++ var error = new Error(); ++ ++ if (error.stack) { ++ return error; ++ } ++ ++ // But some browsers (e.g. Phantom) only provide a stack trace if we throw. ++ try { ++ throw new Error(); ++ } catch (e) { ++ return e; ++ } ++ }; ++ ++ function callerFile() { ++ var trace = new j$.StackTrace(util.errorWithStack()); ++ return trace.frames[2].file; ++ } ++ ++ util.jasmineFile = (function() { ++ var result; ++ ++ return function() { ++ if (!result) { ++ result = callerFile(); ++ } ++ ++ return result; ++ }; ++ })(); ++ ++ function StopIteration() {} ++ StopIteration.prototype = Object.create(Error.prototype); ++ StopIteration.prototype.constructor = StopIteration; ++ ++ // useful for maps and sets since `forEach` is the only IE11-compatible way to iterate them ++ util.forEachBreakable = function(iterable, iteratee) { ++ function breakLoop() { ++ throw new StopIteration(); ++ } ++ ++ try { ++ iterable.forEach(function(value, key) { ++ iteratee(breakLoop, value, key, iterable); ++ }); ++ } catch (error) { ++ if (!(error instanceof StopIteration)) throw error; ++ } ++ }; ++ ++ util.validateTimeout = function(timeout, msgPrefix) { ++ // Timeouts are implemented with setTimeout, which only supports a limited ++ // range of values. The limit is unspecified, as is the behavior when it's ++ // exceeded. But on all currently supported JS runtimes, setTimeout calls ++ // the callback immediately when the timeout is greater than 2147483647 ++ // (the maximum value of a signed 32 bit integer). ++ var max = 2147483647; ++ ++ if (timeout > max) { ++ throw new Error( ++ (msgPrefix || 'Timeout value') + ' cannot be greater than ' + max ++ ); ++ } ++ }; ++ ++ return util; ++}; ++ ++getJasmineRequireObj().Spec = function(j$) { ++ /** ++ * @interface Spec ++ * @see Configuration#specFilter ++ * @since 2.0.0 ++ */ ++ function Spec(attrs) { ++ this.expectationFactory = attrs.expectationFactory; ++ this.asyncExpectationFactory = attrs.asyncExpectationFactory; ++ this.resultCallback = attrs.resultCallback || function() {}; ++ /** ++ * The unique ID of this spec. ++ * @name Spec#id ++ * @readonly ++ * @type {string} ++ * @since 2.0.0 ++ */ ++ this.id = attrs.id; ++ /** ++ * The description passed to the {@link it} that created this spec. ++ * @name Spec#description ++ * @readonly ++ * @type {string} ++ * @since 2.0.0 ++ */ ++ this.description = attrs.description || ''; ++ this.queueableFn = attrs.queueableFn; ++ this.beforeAndAfterFns = ++ attrs.beforeAndAfterFns || ++ function() { ++ return { befores: [], afters: [] }; ++ }; ++ this.userContext = ++ attrs.userContext || ++ function() { ++ return {}; ++ }; ++ this.onStart = attrs.onStart || function() {}; ++ this.autoCleanClosures = ++ attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures; ++ this.getSpecName = ++ attrs.getSpecName || ++ function() { ++ return ''; ++ }; ++ this.expectationResultFactory = ++ attrs.expectationResultFactory || function() {}; ++ this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; ++ this.catchingExceptions = ++ attrs.catchingExceptions || ++ function() { ++ return true; ++ }; ++ this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; ++ this.timer = attrs.timer || new j$.Timer(); ++ ++ if (!this.queueableFn.fn) { ++ this.exclude(); ++ } ++ ++ /** ++ * @typedef SpecResult ++ * @property {Int} id - The unique id of this spec. ++ * @property {String} description - The description passed to the {@link it} that created this spec. ++ * @property {String} fullName - The full description including all ancestors of this spec. ++ * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec. ++ * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec. ++ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec. ++ * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason. ++ * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec. ++ * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach. ++ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty} ++ * @since 2.0.0 ++x */ ++ this.result = { ++ id: this.id, ++ description: this.description, ++ fullName: this.getFullName(), ++ failedExpectations: [], ++ passedExpectations: [], ++ deprecationWarnings: [], ++ pendingReason: '', ++ duration: null, ++ properties: null ++ }; ++ } ++ ++ Spec.prototype.addExpectationResult = function(passed, data, isError) { ++ var expectationResult = this.expectationResultFactory(data); ++ if (passed) { ++ this.result.passedExpectations.push(expectationResult); ++ } else { ++ this.result.failedExpectations.push(expectationResult); ++ ++ if (this.throwOnExpectationFailure && !isError) { ++ throw new j$.errors.ExpectationFailed(); ++ } ++ } ++ }; ++ ++ Spec.prototype.setSpecProperty = function(key, value) { ++ this.result.properties = this.result.properties || {}; ++ this.result.properties[key] = value; ++ }; ++ ++ Spec.prototype.expect = function(actual) { ++ return this.expectationFactory(actual, this); ++ }; ++ ++ Spec.prototype.expectAsync = function(actual) { ++ return this.asyncExpectationFactory(actual, this); ++ }; ++ ++ Spec.prototype.execute = function(onComplete, excluded, failSpecWithNoExp) { ++ var self = this; ++ ++ var onStart = { ++ fn: function(done) { ++ self.timer.start(); ++ self.onStart(self, done); ++ } ++ }; ++ ++ var complete = { ++ fn: function(done) { ++ if (self.autoCleanClosures) { ++ self.queueableFn.fn = null; ++ } ++ self.result.status = self.status(excluded, failSpecWithNoExp); ++ self.result.duration = self.timer.elapsed(); ++ self.resultCallback(self.result, done); ++ } ++ }; ++ ++ var fns = this.beforeAndAfterFns(); ++ var regularFns = fns.befores.concat(this.queueableFn); ++ ++ var runnerConfig = { ++ isLeaf: true, ++ queueableFns: regularFns, ++ cleanupFns: fns.afters, ++ onException: function() { ++ self.onException.apply(self, arguments); ++ }, ++ onComplete: function() { ++ onComplete( ++ self.result.status === 'failed' && ++ new j$.StopExecutionError('spec failed') ++ ); ++ }, ++ userContext: this.userContext() ++ }; ++ ++ if (this.markedPending || excluded === true) { ++ runnerConfig.queueableFns = []; ++ runnerConfig.cleanupFns = []; ++ } ++ ++ runnerConfig.queueableFns.unshift(onStart); ++ runnerConfig.cleanupFns.push(complete); ++ ++ this.queueRunnerFactory(runnerConfig); ++ }; ++ ++ Spec.prototype.reset = function() { ++ /** ++ * @typedef SpecResult ++ * @property {Int} id - The unique id of this spec. ++ * @property {String} description - The description passed to the {@link it} that created this spec. ++ * @property {String} fullName - The full description including all ancestors of this spec. ++ * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec. ++ * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec. ++ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec. ++ * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason. ++ * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec. ++ * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach. ++ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty} ++ * @since 2.0.0 ++ */ ++ this.result = { ++ id: this.id, ++ description: this.description, ++ fullName: this.getFullName(), ++ failedExpectations: [], ++ passedExpectations: [], ++ deprecationWarnings: [], ++ pendingReason: this.excludeMessage, ++ duration: null, ++ properties: null, ++ trace: null ++ }; ++ this.markedPending = this.markedExcluding; ++ }; ++ ++ Spec.prototype.onException = function onException(e) { ++ if (Spec.isPendingSpecException(e)) { ++ this.pend(extractCustomPendingMessage(e)); ++ return; ++ } ++ ++ if (e instanceof j$.errors.ExpectationFailed) { ++ return; ++ } ++ ++ this.addExpectationResult( ++ false, ++ { ++ matcherName: '', ++ passed: false, ++ expected: '', ++ actual: '', ++ error: e ++ }, ++ true ++ ); ++ }; ++ ++ /* ++ * Marks state as pending ++ * @param {string} [message] An optional reason message ++ */ ++ Spec.prototype.pend = function(message) { ++ this.markedPending = true; ++ if (message) { ++ this.result.pendingReason = message; ++ } ++ }; ++ ++ /* ++ * Like {@link Spec#pend}, but pending state will survive {@link Spec#reset} ++ * Useful for fit, xit, where pending state remains. ++ * @param {string} [message] An optional reason message ++ */ ++ Spec.prototype.exclude = function(message) { ++ this.markedExcluding = true; ++ if (this.message) { ++ this.excludeMessage = message; ++ } ++ this.pend(message); ++ }; ++ ++ Spec.prototype.getResult = function() { ++ this.result.status = this.status(); ++ return this.result; ++ }; ++ ++ Spec.prototype.status = function(excluded, failSpecWithNoExpectations) { ++ if (excluded === true) { ++ return 'excluded'; ++ } ++ ++ if (this.markedPending) { ++ return 'pending'; ++ } ++ ++ if ( ++ this.result.failedExpectations.length > 0 || ++ (failSpecWithNoExpectations && ++ this.result.failedExpectations.length + ++ this.result.passedExpectations.length === ++ 0) ++ ) { ++ return 'failed'; ++ } ++ ++ return 'passed'; ++ }; ++ ++ /** ++ * The full description including all ancestors of this spec. ++ * @name Spec#getFullName ++ * @function ++ * @returns {string} ++ * @since 2.0.0 ++ */ ++ Spec.prototype.getFullName = function() { ++ return this.getSpecName(this); ++ }; ++ ++ Spec.prototype.addDeprecationWarning = function(deprecation) { ++ if (typeof deprecation === 'string') { ++ deprecation = { message: deprecation }; ++ } ++ this.result.deprecationWarnings.push( ++ this.expectationResultFactory(deprecation) ++ ); ++ }; ++ ++ var extractCustomPendingMessage = function(e) { ++ var fullMessage = e.toString(), ++ boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), ++ boilerplateEnd = ++ boilerplateStart + Spec.pendingSpecExceptionMessage.length; ++ ++ return fullMessage.substr(boilerplateEnd); ++ }; ++ ++ Spec.pendingSpecExceptionMessage = '=> marked Pending'; ++ ++ Spec.isPendingSpecException = function(e) { ++ return !!( ++ e && ++ e.toString && ++ e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1 ++ ); ++ }; ++ ++ return Spec; ++}; ++ ++if (typeof window == void 0 && typeof exports == 'object') { ++ /* globals exports */ ++ exports.Spec = jasmineRequire.Spec; ++} ++ ++/*jshint bitwise: false*/ ++ ++getJasmineRequireObj().Order = function() { ++ function Order(options) { ++ this.random = 'random' in options ? options.random : true; ++ var seed = (this.seed = options.seed || generateSeed()); ++ this.sort = this.random ? randomOrder : naturalOrder; ++ ++ function naturalOrder(items) { ++ return items; ++ } ++ ++ function randomOrder(items) { ++ var copy = items.slice(); ++ copy.sort(function(a, b) { ++ return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id); ++ }); ++ return copy; ++ } ++ ++ function generateSeed() { ++ return String(Math.random()).slice(-5); ++ } ++ ++ // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function ++ // used to get a different output when the key changes slightly. ++ // We use your return to sort the children randomly in a consistent way when ++ // used in conjunction with a seed ++ ++ function jenkinsHash(key) { ++ var hash, i; ++ for (hash = i = 0; i < key.length; ++i) { ++ hash += key.charCodeAt(i); ++ hash += hash << 10; ++ hash ^= hash >> 6; ++ } ++ hash += hash << 3; ++ hash ^= hash >> 11; ++ hash += hash << 15; ++ return hash; ++ } ++ } ++ ++ return Order; ++}; ++ ++getJasmineRequireObj().Env = function(j$) { ++ /** ++ * @class Env ++ * @since 2.0.0 ++ * @classdesc The Jasmine environment.
++ * _Note:_ Do not construct this directly. You can obtain the Env instance by ++ * calling {@link jasmine.getEnv}. ++ * @hideconstructor ++ */ ++ function Env(options) { ++ options = options || {}; ++ ++ var self = this; ++ var global = options.global || j$.getGlobal(); ++ var customPromise; ++ ++ var totalSpecsDefined = 0; ++ ++ var realSetTimeout = global.setTimeout; ++ var realClearTimeout = global.clearTimeout; ++ var clearStack = j$.getClearStack(global); ++ this.clock = new j$.Clock( ++ global, ++ function() { ++ return new j$.DelayedFunctionScheduler(); ++ }, ++ new j$.MockDate(global) ++ ); ++ ++ var runnableResources = {}; ++ ++ var currentSpec = null; ++ var currentlyExecutingSuites = []; ++ var currentDeclarationSuite = null; ++ var hasFailures = false; ++ ++ /** ++ * This represents the available options to configure Jasmine. ++ * Options that are not provided will use their default values. ++ * @see Env#configure ++ * @interface Configuration ++ * @since 3.3.0 ++ */ ++ var config = { ++ /** ++ * Whether to randomize spec execution order ++ * @name Configuration#random ++ * @since 3.3.0 ++ * @type Boolean ++ * @default true ++ */ ++ random: true, ++ /** ++ * Seed to use as the basis of randomization. ++ * Null causes the seed to be determined randomly at the start of execution. ++ * @name Configuration#seed ++ * @since 3.3.0 ++ * @type (number|string) ++ * @default null ++ */ ++ seed: null, ++ /** ++ * Whether to stop execution of the suite after the first spec failure ++ * @name Configuration#failFast ++ * @since 3.3.0 ++ * @type Boolean ++ * @default false ++ * @deprecated Use the `stopOnSpecFailure` config property instead. ++ */ ++ failFast: false, ++ /** ++ * Whether to stop execution of the suite after the first spec failure ++ * @name Configuration#stopOnSpecFailure ++ * @since 3.9.0 ++ * @type Boolean ++ * @default false ++ */ ++ stopOnSpecFailure: false, ++ /** ++ * Whether to fail the spec if it ran no expectations. By default ++ * a spec that ran no expectations is reported as passed. Setting this ++ * to true will report such spec as a failure. ++ * @name Configuration#failSpecWithNoExpectations ++ * @since 3.5.0 ++ * @type Boolean ++ * @default false ++ */ ++ failSpecWithNoExpectations: false, ++ /** ++ * Whether to cause specs to only have one expectation failure. ++ * @name Configuration#oneFailurePerSpec ++ * @since 3.3.0 ++ * @type Boolean ++ * @default false ++ * @deprecated Use the `stopSpecOnExpectationFailure` config property instead. ++ */ ++ oneFailurePerSpec: false, ++ /** ++ * Whether to cause specs to only have one expectation failure. ++ * @name Configuration#stopSpecOnExpectationFailure ++ * @since 3.3.0 ++ * @type Boolean ++ * @default false ++ */ ++ stopSpecOnExpectationFailure: false, ++ /** ++ * A function that takes a spec and returns true if it should be executed ++ * or false if it should be skipped. ++ * @callback SpecFilter ++ * @param {Spec} spec - The spec that the filter is being applied to. ++ * @return boolean ++ */ ++ /** ++ * Function to use to filter specs ++ * @name Configuration#specFilter ++ * @since 3.3.0 ++ * @type SpecFilter ++ * @default A function that always returns true. ++ */ ++ specFilter: function() { ++ return true; ++ }, ++ /** ++ * Whether or not reporters should hide disabled specs from their output. ++ * Currently only supported by Jasmine's HTMLReporter ++ * @name Configuration#hideDisabled ++ * @since 3.3.0 ++ * @type Boolean ++ * @default false ++ */ ++ hideDisabled: false, ++ /** ++ * Set to provide a custom promise library that Jasmine will use if it needs ++ * to create a promise. If not set, it will default to whatever global Promise ++ * library is available (if any). ++ * @name Configuration#Promise ++ * @since 3.5.0 ++ * @type function ++ * @default undefined ++ */ ++ Promise: undefined, ++ /** ++ * Clean closures when a suite is done running (done by clearing the stored function reference). ++ * This prevents memory leaks, but you won't be able to run jasmine multiple times. ++ * @name Configuration#autoCleanClosures ++ * @since 3.10.0 ++ * @type boolean ++ * @default true ++ */ ++ autoCleanClosures: true ++ }; ++ ++ var currentSuite = function() { ++ return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; ++ }; ++ ++ var currentRunnable = function() { ++ return currentSpec || currentSuite(); ++ }; ++ ++ var globalErrors = null; ++ ++ var installGlobalErrors = function() { ++ if (globalErrors) { ++ return; ++ } ++ ++ globalErrors = new j$.GlobalErrors(); ++ globalErrors.install(); ++ }; ++ ++ if (!options.suppressLoadErrors) { ++ installGlobalErrors(); ++ globalErrors.pushListener(function( ++ message, ++ filename, ++ lineno, ++ colNo, ++ err ++ ) { ++ topSuite.result.failedExpectations.push({ ++ passed: false, ++ globalErrorType: 'load', ++ message: message, ++ stack: err && err.stack, ++ filename: filename, ++ lineno: lineno ++ }); ++ }); ++ } ++ ++ /** ++ * Configure your jasmine environment ++ * @name Env#configure ++ * @since 3.3.0 ++ * @argument {Configuration} configuration ++ * @function ++ */ ++ this.configure = function(configuration) { ++ var booleanProps = [ ++ 'random', ++ 'failSpecWithNoExpectations', ++ 'hideDisabled', ++ 'autoCleanClosures' ++ ]; ++ ++ booleanProps.forEach(function(prop) { ++ if (typeof configuration[prop] !== 'undefined') { ++ config[prop] = !!configuration[prop]; ++ } ++ }); ++ ++ if (typeof configuration.failFast !== 'undefined') { ++ if (typeof configuration.stopOnSpecFailure !== 'undefined') { ++ if (configuration.stopOnSpecFailure !== configuration.failFast) { ++ throw new Error( ++ 'stopOnSpecFailure and failFast are aliases for ' + ++ "each other. Don't set failFast if you also set stopOnSpecFailure." ++ ); ++ } ++ } ++ ++ config.failFast = configuration.failFast; ++ config.stopOnSpecFailure = configuration.failFast; ++ } else if (typeof configuration.stopOnSpecFailure !== 'undefined') { ++ config.failFast = configuration.stopOnSpecFailure; ++ config.stopOnSpecFailure = configuration.stopOnSpecFailure; ++ } ++ ++ if (typeof configuration.oneFailurePerSpec !== 'undefined') { ++ if (typeof configuration.stopSpecOnExpectationFailure !== 'undefined') { ++ if ( ++ configuration.stopSpecOnExpectationFailure !== ++ configuration.oneFailurePerSpec ++ ) { ++ throw new Error( ++ 'stopSpecOnExpectationFailure and oneFailurePerSpec are aliases for ' + ++ "each other. Don't set oneFailurePerSpec if you also set stopSpecOnExpectationFailure." ++ ); ++ } ++ } ++ ++ config.oneFailurePerSpec = configuration.oneFailurePerSpec; ++ config.stopSpecOnExpectationFailure = configuration.oneFailurePerSpec; ++ } else if ( ++ typeof configuration.stopSpecOnExpectationFailure !== 'undefined' ++ ) { ++ config.oneFailurePerSpec = configuration.stopSpecOnExpectationFailure; ++ config.stopSpecOnExpectationFailure = ++ configuration.stopSpecOnExpectationFailure; ++ } ++ ++ if (configuration.specFilter) { ++ config.specFilter = configuration.specFilter; ++ } ++ ++ if (typeof configuration.seed !== 'undefined') { ++ config.seed = configuration.seed; ++ } ++ ++ // Don't use hasOwnProperty to check for Promise existence because Promise ++ // can be initialized to undefined, either explicitly or by using the ++ // object returned from Env#configuration. In particular, Karma does this. ++ if (configuration.Promise) { ++ if ( ++ typeof configuration.Promise.resolve === 'function' && ++ typeof configuration.Promise.reject === 'function' ++ ) { ++ customPromise = configuration.Promise; ++ } else { ++ throw new Error( ++ 'Custom promise library missing `resolve`/`reject` functions' ++ ); ++ } ++ } ++ }; ++ ++ /** ++ * Get the current configuration for your jasmine environment ++ * @name Env#configuration ++ * @since 3.3.0 ++ * @function ++ * @returns {Configuration} ++ */ ++ this.configuration = function() { ++ var result = {}; ++ for (var property in config) { ++ result[property] = config[property]; ++ } ++ return result; ++ }; ++ ++ Object.defineProperty(this, 'specFilter', { ++ get: function() { ++ self.deprecated( ++ 'Getting specFilter directly from Env is deprecated and will be removed in a future version of Jasmine, please check the specFilter option from `configuration`' ++ ); ++ return config.specFilter; ++ }, ++ set: function(val) { ++ self.deprecated( ++ 'Setting specFilter directly on Env is deprecated and will be removed in a future version of Jasmine, please use the specFilter option in `configure`' ++ ); ++ config.specFilter = val; ++ } ++ }); ++ ++ this.setDefaultSpyStrategy = function(defaultStrategyFn) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Default spy strategy must be set in a before function or a spec' ++ ); ++ } ++ runnableResources[ ++ currentRunnable().id ++ ].defaultStrategyFn = defaultStrategyFn; ++ }; ++ ++ this.addSpyStrategy = function(name, fn) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Custom spy strategies must be added in a before function or a spec' ++ ); ++ } ++ runnableResources[currentRunnable().id].customSpyStrategies[name] = fn; ++ }; ++ ++ this.addCustomEqualityTester = function(tester) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Custom Equalities must be added in a before function or a spec' ++ ); ++ } ++ runnableResources[currentRunnable().id].customEqualityTesters.push( ++ tester ++ ); ++ }; ++ ++ this.addMatchers = function(matchersToAdd) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Matchers must be added in a before function or a spec' ++ ); ++ } ++ var customMatchers = ++ runnableResources[currentRunnable().id].customMatchers; ++ ++ for (var matcherName in matchersToAdd) { ++ customMatchers[matcherName] = matchersToAdd[matcherName]; ++ } ++ }; ++ ++ this.addAsyncMatchers = function(matchersToAdd) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Async Matchers must be added in a before function or a spec' ++ ); ++ } ++ var customAsyncMatchers = ++ runnableResources[currentRunnable().id].customAsyncMatchers; ++ ++ for (var matcherName in matchersToAdd) { ++ customAsyncMatchers[matcherName] = matchersToAdd[matcherName]; ++ } ++ }; ++ ++ this.addCustomObjectFormatter = function(formatter) { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Custom object formatters must be added in a before function or a spec' ++ ); ++ } ++ ++ runnableResources[currentRunnable().id].customObjectFormatters.push( ++ formatter ++ ); ++ }; ++ ++ j$.Expectation.addCoreMatchers(j$.matchers); ++ j$.Expectation.addAsyncCoreMatchers(j$.asyncMatchers); ++ ++ var nextSpecId = 0; ++ var getNextSpecId = function() { ++ return 'spec' + nextSpecId++; ++ }; ++ ++ var nextSuiteId = 0; ++ var getNextSuiteId = function() { ++ return 'suite' + nextSuiteId++; ++ }; ++ ++ var makePrettyPrinter = function() { ++ var customObjectFormatters = ++ runnableResources[currentRunnable().id].customObjectFormatters; ++ return j$.makePrettyPrinter(customObjectFormatters); ++ }; ++ ++ var makeMatchersUtil = function() { ++ var customEqualityTesters = ++ runnableResources[currentRunnable().id].customEqualityTesters; ++ return new j$.MatchersUtil({ ++ customTesters: customEqualityTesters, ++ pp: makePrettyPrinter() ++ }); ++ }; ++ ++ var expectationFactory = function(actual, spec) { ++ var customEqualityTesters = ++ runnableResources[spec.id].customEqualityTesters; ++ ++ return j$.Expectation.factory({ ++ matchersUtil: makeMatchersUtil(), ++ customEqualityTesters: customEqualityTesters, ++ customMatchers: runnableResources[spec.id].customMatchers, ++ actual: actual, ++ addExpectationResult: addExpectationResult ++ }); ++ ++ function addExpectationResult(passed, result) { ++ return spec.addExpectationResult(passed, result); ++ } ++ }; ++ ++ function recordLateExpectation(runable, runableType, result) { ++ var delayedExpectationResult = {}; ++ Object.keys(result).forEach(function(k) { ++ delayedExpectationResult[k] = result[k]; ++ }); ++ delayedExpectationResult.passed = false; ++ delayedExpectationResult.globalErrorType = 'lateExpectation'; ++ delayedExpectationResult.message = ++ runableType + ++ ' "' + ++ runable.getFullName() + ++ '" ran a "' + ++ result.matcherName + ++ '" expectation after it finished.\n'; ++ ++ if (result.message) { ++ delayedExpectationResult.message += ++ 'Message: "' + result.message + '"\n'; ++ } ++ ++ delayedExpectationResult.message += ++ '1. Did you forget to return or await the result of expectAsync?\n' + ++ '2. Was done() invoked before an async operation completed?\n' + ++ '3. Did an expectation follow a call to done()?'; ++ ++ topSuite.result.failedExpectations.push(delayedExpectationResult); ++ } ++ ++ var asyncExpectationFactory = function(actual, spec, runableType) { ++ return j$.Expectation.asyncFactory({ ++ matchersUtil: makeMatchersUtil(), ++ customEqualityTesters: runnableResources[spec.id].customEqualityTesters, ++ customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers, ++ actual: actual, ++ addExpectationResult: addExpectationResult ++ }); ++ ++ function addExpectationResult(passed, result) { ++ if (currentRunnable() !== spec) { ++ recordLateExpectation(spec, runableType, result); ++ } ++ return spec.addExpectationResult(passed, result); ++ } ++ }; ++ var suiteAsyncExpectationFactory = function(actual, suite) { ++ return asyncExpectationFactory(actual, suite, 'Suite'); ++ }; ++ ++ var specAsyncExpectationFactory = function(actual, suite) { ++ return asyncExpectationFactory(actual, suite, 'Spec'); ++ }; ++ ++ var defaultResourcesForRunnable = function(id, parentRunnableId) { ++ var resources = { ++ spies: [], ++ customEqualityTesters: [], ++ customMatchers: {}, ++ customAsyncMatchers: {}, ++ customSpyStrategies: {}, ++ defaultStrategyFn: undefined, ++ customObjectFormatters: [] ++ }; ++ ++ if (runnableResources[parentRunnableId]) { ++ resources.customEqualityTesters = j$.util.clone( ++ runnableResources[parentRunnableId].customEqualityTesters ++ ); ++ resources.customMatchers = j$.util.clone( ++ runnableResources[parentRunnableId].customMatchers ++ ); ++ resources.customAsyncMatchers = j$.util.clone( ++ runnableResources[parentRunnableId].customAsyncMatchers ++ ); ++ resources.customObjectFormatters = j$.util.clone( ++ runnableResources[parentRunnableId].customObjectFormatters ++ ); ++ resources.defaultStrategyFn = ++ runnableResources[parentRunnableId].defaultStrategyFn; ++ } ++ ++ runnableResources[id] = resources; ++ }; ++ ++ var clearResourcesForRunnable = function(id) { ++ spyRegistry.clearSpies(); ++ delete runnableResources[id]; ++ }; ++ ++ var beforeAndAfterFns = function(targetSuite) { ++ return function() { ++ var befores = [], ++ afters = [], ++ suite = targetSuite; ++ ++ while (suite) { ++ befores = befores.concat(suite.beforeFns); ++ afters = afters.concat(suite.afterFns); ++ ++ suite = suite.parentSuite; ++ } ++ ++ return { ++ befores: befores.reverse(), ++ afters: afters ++ }; ++ }; ++ }; ++ ++ var getSpecName = function(spec, suite) { ++ var fullName = [spec.description], ++ suiteFullName = suite.getFullName(); ++ ++ if (suiteFullName !== '') { ++ fullName.unshift(suiteFullName); ++ } ++ return fullName.join(' '); ++ }; ++ ++ // TODO: we may just be able to pass in the fn instead of wrapping here ++ var buildExpectationResult = j$.buildExpectationResult, ++ exceptionFormatter = new j$.ExceptionFormatter(), ++ expectationResultFactory = function(attrs) { ++ attrs.messageFormatter = exceptionFormatter.message; ++ attrs.stackFormatter = exceptionFormatter.stack; ++ ++ return buildExpectationResult(attrs); ++ }; ++ ++ /** ++ * Sets whether Jasmine should throw an Error when an expectation fails. ++ * This causes a spec to only have one expectation failure. ++ * @name Env#throwOnExpectationFailure ++ * @since 2.3.0 ++ * @function ++ * @param {Boolean} value Whether to throw when a expectation fails ++ * @deprecated Use the `stopSpecOnExpectationFailure` option with {@link Env#configure} ++ */ ++ this.throwOnExpectationFailure = function(value) { ++ this.deprecated( ++ 'Setting throwOnExpectationFailure directly on Env is deprecated and ' + ++ 'will be removed in a future version of Jasmine. Please use the ' + ++ 'stopSpecOnExpectationFailure option in `configure`.' ++ ); ++ this.configure({ oneFailurePerSpec: !!value }); ++ }; ++ ++ this.throwingExpectationFailures = function() { ++ this.deprecated( ++ 'Getting throwingExpectationFailures directly from Env is deprecated ' + ++ 'and will be removed in a future version of Jasmine. Please check ' + ++ 'the stopSpecOnExpectationFailure option from `configuration`.' ++ ); ++ return config.oneFailurePerSpec; ++ }; ++ ++ /** ++ * Set whether to stop suite execution when a spec fails ++ * @name Env#stopOnSpecFailure ++ * @since 2.7.0 ++ * @function ++ * @param {Boolean} value Whether to stop suite execution when a spec fails ++ * @deprecated Use the `stopOnSpecFailure` option with {@link Env#configure} ++ */ ++ this.stopOnSpecFailure = function(value) { ++ this.deprecated( ++ 'Setting stopOnSpecFailure directly is deprecated and will be ' + ++ 'removed in a future version of Jasmine. Please use the ' + ++ 'stopOnSpecFailure option in `configure`.' ++ ); ++ this.configure({ stopOnSpecFailure: !!value }); ++ }; ++ ++ this.stoppingOnSpecFailure = function() { ++ this.deprecated( ++ 'Getting stoppingOnSpecFailure directly from Env is deprecated and ' + ++ 'will be removed in a future version of Jasmine. Please check the ' + ++ 'stopOnSpecFailure option from `configuration`.' ++ ); ++ return config.failFast; ++ }; ++ ++ /** ++ * Set whether to randomize test execution order ++ * @name Env#randomizeTests ++ * @since 2.4.0 ++ * @function ++ * @param {Boolean} value Whether to randomize execution order ++ * @deprecated Use the `random` option with {@link Env#configure} ++ */ ++ this.randomizeTests = function(value) { ++ this.deprecated( ++ 'Setting randomizeTests directly is deprecated and will be removed in a future version of Jasmine, please use the random option in `configure`' ++ ); ++ config.random = !!value; ++ }; ++ ++ this.randomTests = function() { ++ this.deprecated( ++ 'Getting randomTests directly from Env is deprecated and will be removed in a future version of Jasmine, please check the random option from `configuration`' ++ ); ++ return config.random; ++ }; ++ ++ /** ++ * Set the random number seed for spec randomization ++ * @name Env#seed ++ * @since 2.4.0 ++ * @function ++ * @param {Number} value The seed value ++ * @deprecated Use the `seed` option with {@link Env#configure} ++ */ ++ this.seed = function(value) { ++ this.deprecated( ++ 'Setting seed directly is deprecated and will be removed in a future version of Jasmine, please use the seed option in `configure`' ++ ); ++ if (value) { ++ config.seed = value; ++ } ++ return config.seed; ++ }; ++ ++ this.hidingDisabled = function(value) { ++ this.deprecated( ++ 'Getting hidingDisabled directly from Env is deprecated and will be removed in a future version of Jasmine, please check the hideDisabled option from `configuration`' ++ ); ++ return config.hideDisabled; ++ }; ++ ++ /** ++ * @name Env#hideDisabled ++ * @since 3.2.0 ++ * @function ++ * @deprecated Use the `hideDisabled` option with {@link Env#configure} ++ */ ++ this.hideDisabled = function(value) { ++ this.deprecated( ++ 'Setting hideDisabled directly is deprecated and will be removed in a future version of Jasmine, please use the hideDisabled option in `configure`' ++ ); ++ config.hideDisabled = !!value; ++ }; ++ ++ this.deprecated = function(deprecation) { ++ var runnable = currentRunnable() || topSuite; ++ var context; ++ ++ if (runnable === topSuite) { ++ context = ''; ++ } else if (runnable === currentSuite()) { ++ context = ' (in suite: ' + runnable.getFullName() + ')'; ++ } else { ++ context = ' (in spec: ' + runnable.getFullName() + ')'; ++ } ++ ++ runnable.addDeprecationWarning(deprecation); ++ if ( ++ typeof console !== 'undefined' && ++ typeof console.error === 'function' ++ ) { ++ console.error('DEPRECATION: ' + deprecation + context); ++ } ++ }; ++ ++ var queueRunnerFactory = function(options, args) { ++ var failFast = false; ++ if (options.isLeaf) { ++ failFast = config.stopSpecOnExpectationFailure; ++ } else if (!options.isReporter) { ++ failFast = config.stopOnSpecFailure; ++ } ++ options.clearStack = options.clearStack || clearStack; ++ options.timeout = { ++ setTimeout: realSetTimeout, ++ clearTimeout: realClearTimeout ++ }; ++ options.fail = self.fail; ++ options.globalErrors = globalErrors; ++ options.completeOnFirstError = failFast; ++ options.onException = ++ options.onException || ++ function(e) { ++ (currentRunnable() || topSuite).onException(e); ++ }; ++ options.deprecated = self.deprecated; ++ ++ new j$.QueueRunner(options).execute(args); ++ }; ++ ++ var topSuite = new j$.Suite({ ++ env: this, ++ id: getNextSuiteId(), ++ description: 'Jasmine__TopLevel__Suite', ++ expectationFactory: expectationFactory, ++ asyncExpectationFactory: suiteAsyncExpectationFactory, ++ expectationResultFactory: expectationResultFactory, ++ autoCleanClosures: config.autoCleanClosures ++ }); ++ currentDeclarationSuite = topSuite; ++ ++ /** ++ * Provides the root suite, through which all suites and specs can be ++ * accessed. ++ * @function ++ * @name Env#topSuite ++ * @return {Suite} the root suite ++ * @since 2.0.0 ++ */ ++ this.topSuite = function() { ++ return topSuite; ++ }; ++ ++ /** ++ * This represents the available reporter callback for an object passed to {@link Env#addReporter}. ++ * @interface Reporter ++ * @see custom_reporter ++ */ ++ var reporter = new j$.ReportDispatcher( ++ [ ++ /** ++ * `jasmineStarted` is called after all of the specs have been loaded, but just before execution starts. ++ * @function ++ * @name Reporter#jasmineStarted ++ * @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'jasmineStarted', ++ /** ++ * When the entire suite has finished execution `jasmineDone` is called ++ * @function ++ * @name Reporter#jasmineDone ++ * @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running. ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'jasmineDone', ++ /** ++ * `suiteStarted` is invoked when a `describe` starts to run ++ * @function ++ * @name Reporter#suiteStarted ++ * @param {SuiteResult} result Information about the individual {@link describe} being run ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'suiteStarted', ++ /** ++ * `suiteDone` is invoked when all of the child specs and suites for a given suite have been run ++ * ++ * While jasmine doesn't require any specific functions, not defining a `suiteDone` will make it impossible for a reporter to know when a suite has failures in an `afterAll`. ++ * @function ++ * @name Reporter#suiteDone ++ * @param {SuiteResult} result ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'suiteDone', ++ /** ++ * `specStarted` is invoked when an `it` starts to run (including associated `beforeEach` functions) ++ * @function ++ * @name Reporter#specStarted ++ * @param {SpecResult} result Information about the individual {@link it} being run ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'specStarted', ++ /** ++ * `specDone` is invoked when an `it` and its associated `beforeEach` and `afterEach` functions have been run. ++ * ++ * While jasmine doesn't require any specific functions, not defining a `specDone` will make it impossible for a reporter to know when a spec has failed. ++ * @function ++ * @name Reporter#specDone ++ * @param {SpecResult} result ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ * @see async ++ */ ++ 'specDone' ++ ], ++ queueRunnerFactory ++ ); ++ ++ /** ++ * Executes the specs. ++ * ++ * If called with no parameters or with a falsy value as the first parameter, ++ * all specs will be executed except those that are excluded by a ++ * [spec filter]{@link Configuration#specFilter} or other mechanism. If the ++ * first parameter is a list of spec/suite IDs, only those specs/suites will ++ * be run. ++ * ++ * Both parameters are optional, but a completion callback is only valid as ++ * the second parameter. To specify a completion callback but not a list of ++ * specs/suites to run, pass null or undefined as the first parameter. ++ * ++ * execute should not be called more than once. ++ * ++ * If the environment supports promises, execute will return a promise that ++ * is resolved after the suite finishes executing. The promise will be ++ * resolved (not rejected) as long as the suite runs to completion. Use a ++ * {@link Reporter} to determine whether or not the suite passed. ++ * ++ * @name Env#execute ++ * @since 2.0.0 ++ * @function ++ * @param {(string[])=} runnablesToRun IDs of suites and/or specs to run ++ * @param {Function=} onComplete Function that will be called after all specs have run ++ * @return {Promise} ++ */ ++ this.execute = function(runnablesToRun, onComplete) { ++ if (this._executedBefore) { ++ topSuite.reset(); ++ } ++ this._executedBefore = true; ++ defaultResourcesForRunnable(topSuite.id); ++ installGlobalErrors(); ++ ++ if (!runnablesToRun) { ++ if (focusedRunnables.length) { ++ runnablesToRun = focusedRunnables; ++ } else { ++ runnablesToRun = [topSuite.id]; ++ } ++ } ++ ++ var order = new j$.Order({ ++ random: config.random, ++ seed: config.seed ++ }); ++ ++ var processor = new j$.TreeProcessor({ ++ tree: topSuite, ++ runnableIds: runnablesToRun, ++ queueRunnerFactory: queueRunnerFactory, ++ failSpecWithNoExpectations: config.failSpecWithNoExpectations, ++ nodeStart: function(suite, next) { ++ currentlyExecutingSuites.push(suite); ++ defaultResourcesForRunnable(suite.id, suite.parentSuite.id); ++ reporter.suiteStarted(suite.result, next); ++ suite.startTimer(); ++ }, ++ nodeComplete: function(suite, result, next) { ++ if (suite !== currentSuite()) { ++ throw new Error('Tried to complete the wrong suite'); ++ } ++ ++ clearResourcesForRunnable(suite.id); ++ currentlyExecutingSuites.pop(); ++ ++ if (result.status === 'failed') { ++ hasFailures = true; ++ } ++ suite.endTimer(); ++ reporter.suiteDone(result, next); ++ }, ++ orderChildren: function(node) { ++ return order.sort(node.children); ++ }, ++ excludeNode: function(spec) { ++ return !config.specFilter(spec); ++ } ++ }); ++ ++ if (!processor.processTree().valid) { ++ throw new Error( ++ 'Invalid order: would cause a beforeAll or afterAll to be run multiple times' ++ ); ++ } ++ ++ var jasmineTimer = new j$.Timer(); ++ jasmineTimer.start(); ++ ++ var Promise = customPromise || global.Promise; ++ ++ if (Promise) { ++ return new Promise(function(resolve) { ++ runAll(function() { ++ if (onComplete) { ++ onComplete(); ++ } ++ ++ resolve(); ++ }); ++ }); ++ } else { ++ runAll(function() { ++ if (onComplete) { ++ onComplete(); ++ } ++ }); ++ } ++ ++ function runAll(done) { ++ /** ++ * Information passed to the {@link Reporter#jasmineStarted} event. ++ * @typedef JasmineStartedInfo ++ * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. ++ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. ++ * @since 2.0.0 ++ */ ++ reporter.jasmineStarted( ++ { ++ totalSpecsDefined: totalSpecsDefined, ++ order: order ++ }, ++ function() { ++ currentlyExecutingSuites.push(topSuite); ++ ++ processor.execute(function() { ++ clearResourcesForRunnable(topSuite.id); ++ currentlyExecutingSuites.pop(); ++ var overallStatus, incompleteReason; ++ ++ if ( ++ hasFailures || ++ topSuite.result.failedExpectations.length > 0 ++ ) { ++ overallStatus = 'failed'; ++ } else if (focusedRunnables.length > 0) { ++ overallStatus = 'incomplete'; ++ incompleteReason = 'fit() or fdescribe() was found'; ++ } else if (totalSpecsDefined === 0) { ++ overallStatus = 'incomplete'; ++ incompleteReason = 'No specs found'; ++ } else { ++ overallStatus = 'passed'; ++ } ++ ++ /** ++ * Information passed to the {@link Reporter#jasmineDone} event. ++ * @typedef JasmineDoneInfo ++ * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'. ++ * @property {Int} totalTime - The total time (in ms) that it took to execute the suite ++ * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete. ++ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. ++ * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level. ++ * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level. ++ * @since 2.4.0 ++ */ ++ reporter.jasmineDone( ++ { ++ overallStatus: overallStatus, ++ totalTime: jasmineTimer.elapsed(), ++ incompleteReason: incompleteReason, ++ order: order, ++ failedExpectations: topSuite.result.failedExpectations, ++ deprecationWarnings: topSuite.result.deprecationWarnings ++ }, ++ done ++ ); ++ }); ++ } ++ ); ++ } ++ }; ++ ++ /** ++ * Add a custom reporter to the Jasmine environment. ++ * @name Env#addReporter ++ * @since 2.0.0 ++ * @function ++ * @param {Reporter} reporterToAdd The reporter to be added. ++ * @see custom_reporter ++ */ ++ this.addReporter = function(reporterToAdd) { ++ reporter.addReporter(reporterToAdd); ++ }; ++ ++ /** ++ * Provide a fallback reporter if no other reporters have been specified. ++ * @name Env#provideFallbackReporter ++ * @since 2.5.0 ++ * @function ++ * @param {Reporter} reporterToAdd The reporter ++ * @see custom_reporter ++ */ ++ this.provideFallbackReporter = function(reporterToAdd) { ++ reporter.provideFallbackReporter(reporterToAdd); ++ }; ++ ++ /** ++ * Clear all registered reporters ++ * @name Env#clearReporters ++ * @since 2.5.2 ++ * @function ++ */ ++ this.clearReporters = function() { ++ reporter.clearReporters(); ++ }; ++ ++ var spyFactory = new j$.SpyFactory( ++ function getCustomStrategies() { ++ var runnable = currentRunnable(); ++ ++ if (runnable) { ++ return runnableResources[runnable.id].customSpyStrategies; ++ } ++ ++ return {}; ++ }, ++ function getDefaultStrategyFn() { ++ var runnable = currentRunnable(); ++ ++ if (runnable) { ++ return runnableResources[runnable.id].defaultStrategyFn; ++ } ++ ++ return undefined; ++ }, ++ function getPromise() { ++ return customPromise || global.Promise; ++ } ++ ); ++ ++ var spyRegistry = new j$.SpyRegistry({ ++ currentSpies: function() { ++ if (!currentRunnable()) { ++ throw new Error( ++ 'Spies must be created in a before function or a spec' ++ ); ++ } ++ return runnableResources[currentRunnable().id].spies; ++ }, ++ createSpy: function(name, originalFn) { ++ return self.createSpy(name, originalFn); ++ } ++ }); ++ ++ /** ++ * Configures whether Jasmine should allow the same function to be spied on ++ * more than once during the execution of a spec. By default, spying on ++ * a function that is already a spy will cause an error. ++ * @name Env#allowRespy ++ * @function ++ * @since 2.5.0 ++ * @param {boolean} allow Whether to allow respying ++ */ ++ this.allowRespy = function(allow) { ++ spyRegistry.allowRespy(allow); ++ }; ++ ++ this.spyOn = function() { ++ return spyRegistry.spyOn.apply(spyRegistry, arguments); ++ }; ++ ++ this.spyOnProperty = function() { ++ return spyRegistry.spyOnProperty.apply(spyRegistry, arguments); ++ }; ++ ++ this.spyOnAllFunctions = function() { ++ return spyRegistry.spyOnAllFunctions.apply(spyRegistry, arguments); ++ }; ++ ++ this.createSpy = function(name, originalFn) { ++ if (arguments.length === 1 && j$.isFunction_(name)) { ++ originalFn = name; ++ name = originalFn.name; ++ } ++ ++ return spyFactory.createSpy(name, originalFn); ++ }; ++ ++ this.createSpyObj = function(baseName, methodNames, propertyNames) { ++ return spyFactory.createSpyObj(baseName, methodNames, propertyNames); ++ }; ++ ++ var ensureIsFunction = function(fn, caller) { ++ if (!j$.isFunction_(fn)) { ++ throw new Error( ++ caller + ' expects a function argument; received ' + j$.getType_(fn) ++ ); ++ } ++ }; ++ ++ var ensureIsFunctionOrAsync = function(fn, caller) { ++ if (!j$.isFunction_(fn) && !j$.isAsyncFunction_(fn)) { ++ throw new Error( ++ caller + ' expects a function argument; received ' + j$.getType_(fn) ++ ); ++ } ++ }; ++ ++ function ensureIsNotNested(method) { ++ var runnable = currentRunnable(); ++ if (runnable !== null && runnable !== undefined) { ++ throw new Error( ++ "'" + method + "' should only be used in 'describe' function" ++ ); ++ } ++ } ++ ++ var suiteFactory = function(description) { ++ var suite = new j$.Suite({ ++ env: self, ++ id: getNextSuiteId(), ++ description: description, ++ parentSuite: currentDeclarationSuite, ++ timer: new j$.Timer(), ++ expectationFactory: expectationFactory, ++ asyncExpectationFactory: suiteAsyncExpectationFactory, ++ expectationResultFactory: expectationResultFactory, ++ throwOnExpectationFailure: config.oneFailurePerSpec, ++ autoCleanClosures: config.autoCleanClosures ++ }); ++ ++ return suite; ++ }; ++ ++ this.describe = function(description, specDefinitions) { ++ //ensureIsNotNested('describe'); ++ ensureIsFunction(specDefinitions, 'describe'); ++ var suite = suiteFactory(description); ++ if (specDefinitions.length > 0) { ++ throw new Error('describe does not expect any arguments'); ++ } ++ if (currentDeclarationSuite.markedExcluding) { ++ suite.exclude(); ++ } ++ addSpecsToSuite(suite, specDefinitions); ++ return suite; ++ }; ++ ++ this.xdescribe = function(description, specDefinitions) { ++ ensureIsNotNested('xdescribe'); ++ ensureIsFunction(specDefinitions, 'xdescribe'); ++ var suite = suiteFactory(description); ++ suite.exclude(); ++ addSpecsToSuite(suite, specDefinitions); ++ return suite; ++ }; ++ ++ var focusedRunnables = []; ++ ++ this.fdescribe = function(description, specDefinitions) { ++ ensureIsNotNested('fdescribe'); ++ ensureIsFunction(specDefinitions, 'fdescribe'); ++ var suite = suiteFactory(description); ++ suite.isFocused = true; ++ ++ focusedRunnables.push(suite.id); ++ unfocusAncestor(); ++ addSpecsToSuite(suite, specDefinitions); ++ ++ return suite; ++ }; ++ ++ function addSpecsToSuite(suite, specDefinitions) { ++ var parentSuite = currentDeclarationSuite; ++ parentSuite.addChild(suite); ++ currentDeclarationSuite = suite; ++ ++ var declarationError = null; ++ try { ++ specDefinitions.call(suite); ++ } catch (e) { ++ declarationError = e; ++ } ++ ++ if (declarationError) { ++ suite.onException(declarationError); ++ } ++ ++ currentDeclarationSuite = parentSuite; ++ } ++ ++ function findFocusedAncestor(suite) { ++ while (suite) { ++ if (suite.isFocused) { ++ return suite.id; ++ } ++ suite = suite.parentSuite; ++ } ++ ++ return null; ++ } ++ ++ function unfocusAncestor() { ++ var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); ++ if (focusedAncestor) { ++ for (var i = 0; i < focusedRunnables.length; i++) { ++ if (focusedRunnables[i] === focusedAncestor) { ++ focusedRunnables.splice(i, 1); ++ break; ++ } ++ } ++ } ++ } ++ ++ var specFactory = function(description, fn, suite, timeout) { ++ totalSpecsDefined++; ++ var spec = new j$.Spec({ ++ id: getNextSpecId(), ++ beforeAndAfterFns: beforeAndAfterFns(suite), ++ expectationFactory: expectationFactory, ++ asyncExpectationFactory: specAsyncExpectationFactory, ++ resultCallback: specResultCallback, ++ getSpecName: function(spec) { ++ return getSpecName(spec, suite); ++ }, ++ onStart: specStarted, ++ description: description, ++ expectationResultFactory: expectationResultFactory, ++ queueRunnerFactory: queueRunnerFactory, ++ userContext: function() { ++ return suite.clonedSharedUserContext(); ++ }, ++ queueableFn: { ++ fn: fn, ++ timeout: timeout || 0 ++ }, ++ throwOnExpectationFailure: config.oneFailurePerSpec, ++ autoCleanClosures: config.autoCleanClosures, ++ timer: new j$.Timer() ++ }); ++ return spec; ++ ++ function specResultCallback(result, next) { ++ clearResourcesForRunnable(spec.id); ++ currentSpec = null; ++ ++ if (result.status === 'failed') { ++ hasFailures = true; ++ } ++ ++ reporter.specDone(result, next); ++ } ++ ++ function specStarted(spec, next) { ++ currentSpec = spec; ++ defaultResourcesForRunnable(spec.id, suite.id); ++ reporter.specStarted(spec.result, next); ++ } ++ }; ++ ++ this.it = function(description, fn, timeout) { ++ ensureIsNotNested('it'); ++ // it() sometimes doesn't have a fn argument, so only check the type if ++ // it's given. ++ if (arguments.length > 1 && typeof fn !== 'undefined') { ++ ensureIsFunctionOrAsync(fn, 'it'); ++ } ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ ++ var spec = specFactory(description, fn, currentDeclarationSuite, timeout); ++ if (currentDeclarationSuite.markedExcluding) { ++ spec.exclude(); ++ } ++ currentDeclarationSuite.addChild(spec); ++ return spec; ++ }; ++ ++ this.xit = function(description, fn, timeout) { ++ ensureIsNotNested('xit'); ++ // xit(), like it(), doesn't always have a fn argument, so only check the ++ // type when needed. ++ if (arguments.length > 1 && typeof fn !== 'undefined') { ++ ensureIsFunctionOrAsync(fn, 'xit'); ++ } ++ var spec = this.it.apply(this, arguments); ++ spec.exclude('Temporarily disabled with xit'); ++ return spec; ++ }; ++ ++ this.fit = function(description, fn, timeout) { ++ ensureIsNotNested('fit'); ++ ensureIsFunctionOrAsync(fn, 'fit'); ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ var spec = specFactory(description, fn, currentDeclarationSuite, timeout); ++ currentDeclarationSuite.addChild(spec); ++ focusedRunnables.push(spec.id); ++ unfocusAncestor(); ++ return spec; ++ }; ++ ++ /** ++ * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult} ++ * @name Env#setSpecProperty ++ * @since 3.6.0 ++ * @function ++ * @param {String} key The name of the property ++ * @param {*} value The value of the property ++ */ ++ this.setSpecProperty = function(key, value) { ++ if (!currentRunnable() || currentRunnable() == currentSuite()) { ++ throw new Error( ++ "'setSpecProperty' was used when there was no current spec" ++ ); ++ } ++ currentRunnable().setSpecProperty(key, value); ++ }; ++ ++ /** ++ * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult} ++ * @name Env#setSuiteProperty ++ * @since 3.6.0 ++ * @function ++ * @param {String} key The name of the property ++ * @param {*} value The value of the property ++ */ ++ this.setSuiteProperty = function(key, value) { ++ if (!currentSuite()) { ++ throw new Error( ++ "'setSuiteProperty' was used when there was no current suite" ++ ); ++ } ++ currentSuite().setSuiteProperty(key, value); ++ }; ++ ++ this.expect = function(actual) { ++ if (!currentRunnable()) { ++ throw new Error( ++ "'expect' was used when there was no current spec, this could be because an asynchronous test timed out" ++ ); ++ } ++ ++ return currentRunnable().expect(actual); ++ }; ++ ++ this.expectAsync = function(actual) { ++ if (!currentRunnable()) { ++ throw new Error( ++ "'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out" ++ ); ++ } ++ ++ return currentRunnable().expectAsync(actual); ++ }; ++ ++ this.beforeEach = function(beforeEachFunction, timeout) { ++ ensureIsNotNested('beforeEach'); ++ ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach'); ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ ++ currentDeclarationSuite.beforeEach({ ++ fn: beforeEachFunction, ++ timeout: timeout || 0 ++ }); ++ }; ++ ++ this.beforeAll = function(beforeAllFunction, timeout) { ++ ensureIsNotNested('beforeAll'); ++ ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll'); ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ ++ currentDeclarationSuite.beforeAll({ ++ fn: beforeAllFunction, ++ timeout: timeout || 0 ++ }); ++ }; ++ ++ this.afterEach = function(afterEachFunction, timeout) { ++ ensureIsNotNested('afterEach'); ++ ensureIsFunctionOrAsync(afterEachFunction, 'afterEach'); ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ ++ afterEachFunction.isCleanup = true; ++ currentDeclarationSuite.afterEach({ ++ fn: afterEachFunction, ++ timeout: timeout || 0 ++ }); ++ }; ++ ++ this.afterAll = function(afterAllFunction, timeout) { ++ ensureIsNotNested('afterAll'); ++ ensureIsFunctionOrAsync(afterAllFunction, 'afterAll'); ++ ++ if (timeout) { ++ j$.util.validateTimeout(timeout); ++ } ++ ++ currentDeclarationSuite.afterAll({ ++ fn: afterAllFunction, ++ timeout: timeout || 0 ++ }); ++ }; ++ ++ this.pending = function(message) { ++ var fullMessage = j$.Spec.pendingSpecExceptionMessage; ++ if (message) { ++ fullMessage += message; ++ } ++ throw fullMessage; ++ }; ++ ++ this.fail = function(error) { ++ if (!currentRunnable()) { ++ throw new Error( ++ "'fail' was used when there was no current spec, this could be because an asynchronous test timed out" ++ ); ++ } ++ ++ var message = 'Failed'; ++ if (error) { ++ message += ': '; ++ if (error.message) { ++ message += error.message; ++ } else if (j$.isString_(error)) { ++ message += error; ++ } else { ++ // pretty print all kind of objects. This includes arrays. ++ message += makePrettyPrinter()(error); ++ } ++ } ++ ++ currentRunnable().addExpectationResult(false, { ++ matcherName: '', ++ passed: false, ++ expected: '', ++ actual: '', ++ message: message, ++ error: error && error.message ? error : null ++ }); ++ ++ if (config.oneFailurePerSpec) { ++ throw new Error(message); ++ } ++ }; ++ ++ this.cleanup_ = function() { ++ if (globalErrors) { ++ globalErrors.uninstall(); ++ } ++ }; ++ } ++ ++ return Env; ++}; ++ ++getJasmineRequireObj().JsApiReporter = function(j$) { ++ /** ++ * @name jsApiReporter ++ * @classdesc {@link Reporter} added by default in `boot.js` to record results for retrieval in javascript code. An instance is made available as `jsApiReporter` on the global object. ++ * @class ++ * @hideconstructor ++ */ ++ function JsApiReporter(options) { ++ var timer = options.timer || new j$.Timer(), ++ status = 'loaded'; ++ ++ this.started = false; ++ this.finished = false; ++ this.runDetails = {}; ++ ++ this.jasmineStarted = function() { ++ this.started = true; ++ status = 'started'; ++ timer.start(); ++ }; ++ ++ var executionTime; ++ ++ this.jasmineDone = function(runDetails) { ++ this.finished = true; ++ this.runDetails = runDetails; ++ executionTime = timer.elapsed(); ++ status = 'done'; ++ }; ++ ++ /** ++ * Get the current status for the Jasmine environment. ++ * @name jsApiReporter#status ++ * @since 2.0.0 ++ * @function ++ * @return {String} - One of `loaded`, `started`, or `done` ++ */ ++ this.status = function() { ++ return status; ++ }; ++ ++ var suites = [], ++ suites_hash = {}; ++ ++ this.suiteStarted = function(result) { ++ suites_hash[result.id] = result; ++ }; ++ ++ this.suiteDone = function(result) { ++ storeSuite(result); ++ }; ++ ++ /** ++ * Get the results for a set of suites. ++ * ++ * Retrievable in slices for easier serialization. ++ * @name jsApiReporter#suiteResults ++ * @since 2.1.0 ++ * @function ++ * @param {Number} index - The position in the suites list to start from. ++ * @param {Number} length - Maximum number of suite results to return. ++ * @return {SuiteResult[]} ++ */ ++ this.suiteResults = function(index, length) { ++ return suites.slice(index, index + length); ++ }; ++ ++ function storeSuite(result) { ++ suites.push(result); ++ suites_hash[result.id] = result; ++ } ++ ++ /** ++ * Get all of the suites in a single object, with their `id` as the key. ++ * @name jsApiReporter#suites ++ * @since 2.0.0 ++ * @function ++ * @return {Object} - Map of suite id to {@link SuiteResult} ++ */ ++ this.suites = function() { ++ return suites_hash; ++ }; ++ ++ var specs = []; ++ ++ this.specDone = function(result) { ++ specs.push(result); ++ }; ++ ++ /** ++ * Get the results for a set of specs. ++ * ++ * Retrievable in slices for easier serialization. ++ * @name jsApiReporter#specResults ++ * @since 2.0.0 ++ * @function ++ * @param {Number} index - The position in the specs list to start from. ++ * @param {Number} length - Maximum number of specs results to return. ++ * @return {SpecResult[]} ++ */ ++ this.specResults = function(index, length) { ++ return specs.slice(index, index + length); ++ }; ++ ++ /** ++ * Get all spec results. ++ * @name jsApiReporter#specs ++ * @since 2.0.0 ++ * @function ++ * @return {SpecResult[]} ++ */ ++ this.specs = function() { ++ return specs; ++ }; ++ ++ /** ++ * Get the number of milliseconds it took for the full Jasmine suite to run. ++ * @name jsApiReporter#executionTime ++ * @since 2.0.0 ++ * @function ++ * @return {Number} ++ */ ++ this.executionTime = function() { ++ return executionTime; ++ }; ++ } ++ ++ return JsApiReporter; ++}; ++ ++getJasmineRequireObj().Any = function(j$) { ++ function Any(expectedObject) { ++ if (typeof expectedObject === 'undefined') { ++ throw new TypeError( ++ 'jasmine.any() expects to be passed a constructor function. ' + ++ 'Please pass one or use jasmine.anything() to match any object.' ++ ); ++ } ++ this.expectedObject = expectedObject; ++ } ++ ++ Any.prototype.asymmetricMatch = function(other) { ++ if (this.expectedObject == String) { ++ return typeof other == 'string' || other instanceof String; ++ } ++ ++ if (this.expectedObject == Number) { ++ return typeof other == 'number' || other instanceof Number; ++ } ++ ++ if (this.expectedObject == Function) { ++ return typeof other == 'function' || other instanceof Function; ++ } ++ ++ if (this.expectedObject == Object) { ++ return other !== null && typeof other == 'object'; ++ } ++ ++ if (this.expectedObject == Boolean) { ++ return typeof other == 'boolean'; ++ } ++ ++ /* jshint -W122 */ ++ /* global Symbol */ ++ if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) { ++ return typeof other == 'symbol'; ++ } ++ /* jshint +W122 */ ++ ++ return other instanceof this.expectedObject; ++ }; ++ ++ Any.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return Any; ++}; ++ ++getJasmineRequireObj().Anything = function(j$) { ++ function Anything() {} ++ ++ Anything.prototype.asymmetricMatch = function(other) { ++ return !j$.util.isUndefined(other) && other !== null; ++ }; ++ ++ Anything.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return Anything; ++}; ++ ++getJasmineRequireObj().ArrayContaining = function(j$) { ++ function ArrayContaining(sample) { ++ this.sample = sample; ++ } ++ ++ ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) { ++ if (!j$.isArray_(this.sample)) { ++ throw new Error( ++ 'You must provide an array to arrayContaining, not ' + ++ j$.pp(this.sample) + ++ '.' ++ ); ++ } ++ ++ // If the actual parameter is not an array, we can fail immediately, since it couldn't ++ // possibly be an "array containing" anything. However, we also want an empty sample ++ // array to match anything, so we need to double-check we aren't in that case ++ if (!j$.isArray_(other) && this.sample.length > 0) { ++ return false; ++ } ++ ++ for (var i = 0; i < this.sample.length; i++) { ++ var item = this.sample[i]; ++ if (!matchersUtil.contains(other, item)) { ++ return false; ++ } ++ } ++ ++ return true; ++ }; ++ ++ ArrayContaining.prototype.jasmineToString = function(pp) { ++ return ''; ++ }; ++ ++ return ArrayContaining; ++}; ++ ++getJasmineRequireObj().ArrayWithExactContents = function(j$) { ++ function ArrayWithExactContents(sample) { ++ this.sample = sample; ++ } ++ ++ ArrayWithExactContents.prototype.asymmetricMatch = function( ++ other, ++ matchersUtil ++ ) { ++ if (!j$.isArray_(this.sample)) { ++ throw new Error( ++ 'You must provide an array to arrayWithExactContents, not ' + ++ j$.pp(this.sample) + ++ '.' ++ ); ++ } ++ ++ if (this.sample.length !== other.length) { ++ return false; ++ } ++ ++ for (var i = 0; i < this.sample.length; i++) { ++ var item = this.sample[i]; ++ if (!matchersUtil.contains(other, item)) { ++ return false; ++ } ++ } ++ ++ return true; ++ }; ++ ++ ArrayWithExactContents.prototype.jasmineToString = function(pp) { ++ return ''; ++ }; ++ ++ return ArrayWithExactContents; ++}; ++ ++getJasmineRequireObj().Empty = function(j$) { ++ function Empty() {} ++ ++ Empty.prototype.asymmetricMatch = function(other) { ++ if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) { ++ return other.length === 0; ++ } ++ ++ if (j$.isMap(other) || j$.isSet(other)) { ++ return other.size === 0; ++ } ++ ++ if (j$.isObject_(other)) { ++ return Object.keys(other).length === 0; ++ } ++ return false; ++ }; ++ ++ Empty.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return Empty; ++}; ++ ++getJasmineRequireObj().Falsy = function(j$) { ++ function Falsy() {} ++ ++ Falsy.prototype.asymmetricMatch = function(other) { ++ return !other; ++ }; ++ ++ Falsy.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return Falsy; ++}; ++ ++getJasmineRequireObj().MapContaining = function(j$) { ++ function MapContaining(sample) { ++ if (!j$.isMap(sample)) { ++ throw new Error( ++ 'You must provide a map to `mapContaining`, not ' + j$.pp(sample) ++ ); ++ } ++ ++ this.sample = sample; ++ } ++ ++ MapContaining.prototype.asymmetricMatch = function(other, matchersUtil) { ++ if (!j$.isMap(other)) return false; ++ ++ var hasAllMatches = true; ++ j$.util.forEachBreakable(this.sample, function(breakLoop, value, key) { ++ // for each key/value pair in `sample` ++ // there should be at least one pair in `other` whose key and value both match ++ var hasMatch = false; ++ j$.util.forEachBreakable(other, function(oBreakLoop, oValue, oKey) { ++ if ( ++ matchersUtil.equals(oKey, key) && ++ matchersUtil.equals(oValue, value) ++ ) { ++ hasMatch = true; ++ oBreakLoop(); ++ } ++ }); ++ if (!hasMatch) { ++ hasAllMatches = false; ++ breakLoop(); ++ } ++ }); ++ ++ return hasAllMatches; ++ }; ++ ++ MapContaining.prototype.jasmineToString = function(pp) { ++ return ''; ++ }; ++ ++ return MapContaining; ++}; ++ ++getJasmineRequireObj().NotEmpty = function(j$) { ++ function NotEmpty() {} ++ ++ NotEmpty.prototype.asymmetricMatch = function(other) { ++ if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) { ++ return other.length !== 0; ++ } ++ ++ if (j$.isMap(other) || j$.isSet(other)) { ++ return other.size !== 0; ++ } ++ ++ if (j$.isObject_(other)) { ++ return Object.keys(other).length !== 0; ++ } ++ ++ return false; ++ }; ++ ++ NotEmpty.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return NotEmpty; ++}; ++ ++getJasmineRequireObj().ObjectContaining = function(j$) { ++ function ObjectContaining(sample) { ++ this.sample = sample; ++ } ++ ++ function getPrototype(obj) { ++ if (Object.getPrototypeOf) { ++ return Object.getPrototypeOf(obj); ++ } ++ ++ if (obj.constructor.prototype == obj) { ++ return null; ++ } ++ ++ return obj.constructor.prototype; ++ } ++ ++ function hasProperty(obj, property) { ++ if (!obj || typeof obj !== 'object') { ++ return false; ++ } ++ ++ if (Object.prototype.hasOwnProperty.call(obj, property)) { ++ return true; ++ } ++ ++ return hasProperty(getPrototype(obj), property); ++ } ++ ++ ObjectContaining.prototype.asymmetricMatch = function(other, matchersUtil) { ++ if (typeof this.sample !== 'object') { ++ throw new Error( ++ "You must provide an object to objectContaining, not '" + ++ this.sample + ++ "'." ++ ); ++ } ++ if (typeof other !== 'object') { ++ return false; ++ } ++ ++ for (var property in this.sample) { ++ if ( ++ !hasProperty(other, property) || ++ !matchersUtil.equals(this.sample[property], other[property]) ++ ) { ++ return false; ++ } ++ } ++ ++ return true; ++ }; ++ ++ ObjectContaining.prototype.valuesForDiff_ = function(other, pp) { ++ if (!j$.isObject_(other)) { ++ return { ++ self: this.jasmineToString(pp), ++ other: other ++ }; ++ } ++ ++ var filteredOther = {}; ++ Object.keys(this.sample).forEach(function(k) { ++ // eq short-circuits comparison of objects that have different key sets, ++ // so include all keys even if undefined. ++ filteredOther[k] = other[k]; ++ }); ++ ++ return { ++ self: this.sample, ++ other: filteredOther ++ }; ++ }; ++ ++ ObjectContaining.prototype.jasmineToString = function(pp) { ++ return ''; ++ }; ++ ++ return ObjectContaining; ++}; ++ ++getJasmineRequireObj().SetContaining = function(j$) { ++ function SetContaining(sample) { ++ if (!j$.isSet(sample)) { ++ throw new Error( ++ 'You must provide a set to `setContaining`, not ' + j$.pp(sample) ++ ); ++ } ++ ++ this.sample = sample; ++ } ++ ++ SetContaining.prototype.asymmetricMatch = function(other, matchersUtil) { ++ if (!j$.isSet(other)) return false; ++ ++ var hasAllMatches = true; ++ j$.util.forEachBreakable(this.sample, function(breakLoop, item) { ++ // for each item in `sample` there should be at least one matching item in `other` ++ // (not using `matchersUtil.contains` because it compares set members by reference, ++ // not by deep value equality) ++ var hasMatch = false; ++ j$.util.forEachBreakable(other, function(oBreakLoop, oItem) { ++ if (matchersUtil.equals(oItem, item)) { ++ hasMatch = true; ++ oBreakLoop(); ++ } ++ }); ++ if (!hasMatch) { ++ hasAllMatches = false; ++ breakLoop(); ++ } ++ }); ++ ++ return hasAllMatches; ++ }; ++ ++ SetContaining.prototype.jasmineToString = function(pp) { ++ return ''; ++ }; ++ ++ return SetContaining; ++}; ++ ++getJasmineRequireObj().StringContaining = function(j$) { ++ function StringContaining(expected) { ++ if (!j$.isString_(expected)) { ++ throw new Error('Expected is not a String'); ++ } ++ ++ this.expected = expected; ++ } ++ ++ StringContaining.prototype.asymmetricMatch = function(other) { ++ if (!j$.isString_(other)) { ++ // Arrays, etc. don't match no matter what their indexOf returns. ++ return false; ++ } ++ ++ return other.indexOf(this.expected) !== -1; ++ }; ++ ++ StringContaining.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return StringContaining; ++}; ++ ++getJasmineRequireObj().StringMatching = function(j$) { ++ function StringMatching(expected) { ++ if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { ++ throw new Error('Expected is not a String or a RegExp'); ++ } ++ ++ this.regexp = new RegExp(expected); ++ } ++ ++ StringMatching.prototype.asymmetricMatch = function(other) { ++ return this.regexp.test(other); ++ }; ++ ++ StringMatching.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return StringMatching; ++}; ++ ++getJasmineRequireObj().Truthy = function(j$) { ++ function Truthy() {} ++ ++ Truthy.prototype.asymmetricMatch = function(other) { ++ return !!other; ++ }; ++ ++ Truthy.prototype.jasmineToString = function() { ++ return ''; ++ }; ++ ++ return Truthy; ++}; ++ ++getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) { ++ /* ++ Older versions of Jasmine passed an array of custom equality testers as the ++ second argument to each asymmetric equality tester's `asymmetricMatch` ++ method. Newer versions will pass a `MatchersUtil` instance. The ++ asymmetricEqualityTesterArgCompatShim allows for a graceful migration from ++ the old interface to the new by "being" both an array of custom equality ++ testers and a `MatchersUtil` at the same time. ++ ++ This code should be removed in the next major release. ++ */ ++ ++ var likelyArrayProps = [ ++ 'concat', ++ 'constructor', ++ 'copyWithin', ++ 'entries', ++ 'every', ++ 'fill', ++ 'filter', ++ 'find', ++ 'findIndex', ++ 'flat', ++ 'flatMap', ++ 'forEach', ++ 'includes', ++ 'indexOf', ++ 'join', ++ 'keys', ++ 'lastIndexOf', ++ 'length', ++ 'map', ++ 'pop', ++ 'push', ++ 'reduce', ++ 'reduceRight', ++ 'reverse', ++ 'shift', ++ 'slice', ++ 'some', ++ 'sort', ++ 'splice', ++ 'toLocaleString', ++ 'toSource', ++ 'toString', ++ 'unshift', ++ 'values' ++ ]; ++ ++ function asymmetricEqualityTesterArgCompatShim( ++ matchersUtil, ++ customEqualityTesters ++ ) { ++ var self = Object.create(matchersUtil), ++ props, ++ i, ++ k; ++ ++ copy(self, customEqualityTesters, 'length'); ++ ++ for (i = 0; i < customEqualityTesters.length; i++) { ++ copy(self, customEqualityTesters, i); ++ } ++ ++ var props = arrayProps(); ++ ++ for (i = 0; i < props.length; i++) { ++ k = props[i]; ++ // Skip length (dealt with above), and anything that collides with ++ // MatchesUtil e.g. an Array.prototype.contains method added by user code ++ if (k !== 'length' && !self[k]) { ++ copy(self, Array.prototype, k); ++ } ++ } ++ ++ return self; ++ } ++ ++ function copy(dest, src, propName) { ++ Object.defineProperty(dest, propName, { ++ get: function() { ++ return src[propName]; ++ } ++ }); ++ } ++ ++ function arrayProps() { ++ var props, a, k; ++ ++ if (!Object.getOwnPropertyDescriptors) { ++ return likelyArrayProps.filter(function(k) { ++ return Array.prototype.hasOwnProperty(k); ++ }); ++ } ++ ++ props = Object.getOwnPropertyDescriptors(Array.prototype); // eslint-disable-line compat/compat ++ a = []; ++ ++ for (k in props) { ++ a.push(k); ++ } ++ ++ return a; ++ } ++ ++ return asymmetricEqualityTesterArgCompatShim; ++}; ++ ++getJasmineRequireObj().CallTracker = function(j$) { ++ /** ++ * @namespace Spy#calls ++ * @since 2.0.0 ++ */ ++ function CallTracker() { ++ var calls = []; ++ var opts = {}; ++ ++ this.track = function(context) { ++ if (opts.cloneArgs) { ++ context.args = j$.util.cloneArgs(context.args); ++ } ++ calls.push(context); ++ }; ++ ++ /** ++ * Check whether this spy has been invoked. ++ * @name Spy#calls#any ++ * @since 2.0.0 ++ * @function ++ * @return {Boolean} ++ */ ++ this.any = function() { ++ return !!calls.length; ++ }; ++ ++ /** ++ * Get the number of invocations of this spy. ++ * @name Spy#calls#count ++ * @since 2.0.0 ++ * @function ++ * @return {Integer} ++ */ ++ this.count = function() { ++ return calls.length; ++ }; ++ ++ /** ++ * Get the arguments that were passed to a specific invocation of this spy. ++ * @name Spy#calls#argsFor ++ * @since 2.0.0 ++ * @function ++ * @param {Integer} index The 0-based invocation index. ++ * @return {Array} ++ */ ++ this.argsFor = function(index) { ++ var call = calls[index]; ++ return call ? call.args : []; ++ }; ++ ++ /** ++ * Get the "this" object that was passed to a specific invocation of this spy. ++ * @name Spy#calls#thisFor ++ * @since 3.8.0 ++ * @function ++ * @param {Integer} index The 0-based invocation index. ++ * @return {Object?} ++ */ ++ this.thisFor = function(index) { ++ var call = calls[index]; ++ return call ? call.object : undefined; ++ }; ++ ++ /** ++ * Get the raw calls array for this spy. ++ * @name Spy#calls#all ++ * @since 2.0.0 ++ * @function ++ * @return {Spy.callData[]} ++ */ ++ this.all = function() { ++ return calls; ++ }; ++ ++ /** ++ * Get all of the arguments for each invocation of this spy in the order they were received. ++ * @name Spy#calls#allArgs ++ * @since 2.0.0 ++ * @function ++ * @return {Array} ++ */ ++ this.allArgs = function() { ++ var callArgs = []; ++ for (var i = 0; i < calls.length; i++) { ++ callArgs.push(calls[i].args); ++ } ++ ++ return callArgs; ++ }; ++ ++ /** ++ * Get the first invocation of this spy. ++ * @name Spy#calls#first ++ * @since 2.0.0 ++ * @function ++ * @return {ObjecSpy.callData} ++ */ ++ this.first = function() { ++ return calls[0]; ++ }; ++ ++ /** ++ * Get the most recent invocation of this spy. ++ * @name Spy#calls#mostRecent ++ * @since 2.0.0 ++ * @function ++ * @return {ObjecSpy.callData} ++ */ ++ this.mostRecent = function() { ++ return calls[calls.length - 1]; ++ }; ++ ++ /** ++ * Reset this spy as if it has never been called. ++ * @name Spy#calls#reset ++ * @since 2.0.0 ++ * @function ++ */ ++ this.reset = function() { ++ calls = []; ++ }; ++ ++ /** ++ * Set this spy to do a shallow clone of arguments passed to each invocation. ++ * @name Spy#calls#saveArgumentsByValue ++ * @since 2.5.0 ++ * @function ++ */ ++ this.saveArgumentsByValue = function() { ++ opts.cloneArgs = true; ++ }; ++ } ++ ++ return CallTracker; ++}; ++ ++getJasmineRequireObj().clearStack = function(j$) { ++ var maxInlineCallCount = 10; ++ ++ function messageChannelImpl(global, setTimeout) { ++ var channel = new global.MessageChannel(), ++ head = {}, ++ tail = head; ++ ++ var taskRunning = false; ++ channel.port1.onmessage = function() { ++ head = head.next; ++ var task = head.task; ++ delete head.task; ++ ++ if (taskRunning) { ++ global.setTimeout(task, 0); ++ } else { ++ try { ++ taskRunning = true; ++ task(); ++ } finally { ++ taskRunning = false; ++ } ++ } ++ }; ++ ++ var currentCallCount = 0; ++ return function clearStack(fn) { ++ currentCallCount++; ++ ++ if (currentCallCount < maxInlineCallCount) { ++ tail = tail.next = { task: fn }; ++ channel.port2.postMessage(0); ++ } else { ++ currentCallCount = 0; ++ setTimeout(fn); ++ } ++ }; ++ } ++ ++ function getClearStack(global) { ++ var currentCallCount = 0; ++ var realSetTimeout = global.setTimeout; ++ var setTimeoutImpl = function clearStack(fn) { ++ Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]); ++ }; ++ ++ if (j$.isFunction_(global.setImmediate)) { ++ var realSetImmediate = global.setImmediate; ++ return function(fn) { ++ currentCallCount++; ++ ++ if (currentCallCount < maxInlineCallCount) { ++ realSetImmediate(fn); ++ } else { ++ currentCallCount = 0; ++ ++ setTimeoutImpl(fn); ++ } ++ }; ++ } else if (!j$.util.isUndefined(global.MessageChannel)) { ++ return messageChannelImpl(global, setTimeoutImpl); ++ } else { ++ return setTimeoutImpl; ++ } ++ } ++ ++ return getClearStack; ++}; ++ ++getJasmineRequireObj().Clock = function() { ++ /* global process */ ++ var NODE_JS = ++ typeof process !== 'undefined' && ++ process.versions && ++ typeof process.versions.node === 'string'; ++ ++ /** ++ * @class Clock ++ * @since 1.3.0 ++ * @classdesc Jasmine's mock clock is used when testing time dependent code.
++ * _Note:_ Do not construct this directly. You can get the current clock with ++ * {@link jasmine.clock}. ++ * @hideconstructor ++ */ ++ function Clock(global, delayedFunctionSchedulerFactory, mockDate) { ++ var self = this, ++ realTimingFunctions = { ++ setTimeout: global.setTimeout, ++ clearTimeout: global.clearTimeout, ++ setInterval: global.setInterval, ++ clearInterval: global.clearInterval ++ }, ++ fakeTimingFunctions = { ++ setTimeout: setTimeout, ++ clearTimeout: clearTimeout, ++ setInterval: setInterval, ++ clearInterval: clearInterval ++ }, ++ installed = false, ++ delayedFunctionScheduler, ++ timer; ++ ++ self.FakeTimeout = FakeTimeout; ++ ++ /** ++ * Install the mock clock over the built-in methods. ++ * @name Clock#install ++ * @since 2.0.0 ++ * @function ++ * @return {Clock} ++ */ ++ self.install = function() { ++ if (!originalTimingFunctionsIntact()) { ++ throw new Error( ++ 'Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?' ++ ); ++ } ++ replace(global, fakeTimingFunctions); ++ timer = fakeTimingFunctions; ++ delayedFunctionScheduler = delayedFunctionSchedulerFactory(); ++ installed = true; ++ ++ return self; ++ }; ++ ++ /** ++ * Uninstall the mock clock, returning the built-in methods to their places. ++ * @name Clock#uninstall ++ * @since 2.0.0 ++ * @function ++ */ ++ self.uninstall = function() { ++ delayedFunctionScheduler = null; ++ mockDate.uninstall(); ++ replace(global, realTimingFunctions); ++ ++ timer = realTimingFunctions; ++ installed = false; ++ }; ++ ++ /** ++ * Execute a function with a mocked Clock ++ * ++ * The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes. ++ * @name Clock#withMock ++ * @since 2.3.0 ++ * @function ++ * @param {Function} closure The function to be called. ++ */ ++ self.withMock = function(closure) { ++ this.install(); ++ try { ++ closure(); ++ } finally { ++ this.uninstall(); ++ } ++ }; ++ ++ /** ++ * Instruct the installed Clock to also mock the date returned by `new Date()` ++ * @name Clock#mockDate ++ * @since 2.1.0 ++ * @function ++ * @param {Date} [initialDate=now] The `Date` to provide. ++ */ ++ self.mockDate = function(initialDate) { ++ mockDate.install(initialDate); ++ }; ++ ++ self.setTimeout = function(fn, delay, params) { ++ return Function.prototype.apply.apply(timer.setTimeout, [ ++ global, ++ arguments ++ ]); ++ }; ++ ++ self.setInterval = function(fn, delay, params) { ++ return Function.prototype.apply.apply(timer.setInterval, [ ++ global, ++ arguments ++ ]); ++ }; ++ ++ self.clearTimeout = function(id) { ++ return Function.prototype.call.apply(timer.clearTimeout, [global, id]); ++ }; ++ ++ self.clearInterval = function(id) { ++ return Function.prototype.call.apply(timer.clearInterval, [global, id]); ++ }; ++ ++ /** ++ * Tick the Clock forward, running any enqueued timeouts along the way ++ * @name Clock#tick ++ * @since 1.3.0 ++ * @function ++ * @param {int} millis The number of milliseconds to tick. ++ */ ++ self.tick = function(millis) { ++ if (installed) { ++ delayedFunctionScheduler.tick(millis, function(millis) { ++ mockDate.tick(millis); ++ }); ++ } else { ++ throw new Error( ++ 'Mock clock is not installed, use jasmine.clock().install()' ++ ); ++ } ++ }; ++ ++ return self; ++ ++ function originalTimingFunctionsIntact() { ++ return ( ++ global.setTimeout === realTimingFunctions.setTimeout && ++ global.clearTimeout === realTimingFunctions.clearTimeout && ++ global.setInterval === realTimingFunctions.setInterval && ++ global.clearInterval === realTimingFunctions.clearInterval ++ ); ++ } ++ ++ function replace(dest, source) { ++ for (var prop in source) { ++ dest[prop] = source[prop]; ++ } ++ } ++ ++ function setTimeout(fn, delay) { ++ if (!NODE_JS) { ++ return delayedFunctionScheduler.scheduleFunction( ++ fn, ++ delay, ++ argSlice(arguments, 2) ++ ); ++ } ++ ++ var timeout = new FakeTimeout(); ++ ++ delayedFunctionScheduler.scheduleFunction( ++ fn, ++ delay, ++ argSlice(arguments, 2), ++ false, ++ timeout ++ ); ++ ++ return timeout; ++ } ++ ++ function clearTimeout(id) { ++ return delayedFunctionScheduler.removeFunctionWithId(id); ++ } ++ ++ function setInterval(fn, interval) { ++ if (!NODE_JS) { ++ return delayedFunctionScheduler.scheduleFunction( ++ fn, ++ interval, ++ argSlice(arguments, 2), ++ true ++ ); ++ } ++ ++ var timeout = new FakeTimeout(); ++ ++ delayedFunctionScheduler.scheduleFunction( ++ fn, ++ interval, ++ argSlice(arguments, 2), ++ true, ++ timeout ++ ); ++ ++ return timeout; ++ } ++ ++ function clearInterval(id) { ++ return delayedFunctionScheduler.removeFunctionWithId(id); ++ } ++ ++ function argSlice(argsObj, n) { ++ return Array.prototype.slice.call(argsObj, n); ++ } ++ } ++ ++ /** ++ * Mocks Node.js Timeout class ++ */ ++ function FakeTimeout() {} ++ ++ FakeTimeout.prototype.ref = function() { ++ return this; ++ }; ++ ++ FakeTimeout.prototype.unref = function() { ++ return this; ++ }; ++ ++ return Clock; ++}; ++ ++getJasmineRequireObj().DelayedFunctionScheduler = function(j$) { ++ function DelayedFunctionScheduler() { ++ var self = this; ++ var scheduledLookup = []; ++ var scheduledFunctions = {}; ++ var currentTime = 0; ++ var delayedFnCount = 0; ++ var deletedKeys = []; ++ ++ self.tick = function(millis, tickDate) { ++ millis = millis || 0; ++ var endTime = currentTime + millis; ++ ++ runScheduledFunctions(endTime, tickDate); ++ currentTime = endTime; ++ }; ++ ++ self.scheduleFunction = function( ++ funcToCall, ++ millis, ++ params, ++ recurring, ++ timeoutKey, ++ runAtMillis ++ ) { ++ var f; ++ if (typeof funcToCall === 'string') { ++ /* jshint evil: true */ ++ f = function() { ++ return eval(funcToCall); ++ }; ++ /* jshint evil: false */ ++ } else { ++ f = funcToCall; ++ } ++ ++ millis = millis || 0; ++ timeoutKey = timeoutKey || ++delayedFnCount; ++ runAtMillis = runAtMillis || currentTime + millis; ++ ++ var funcToSchedule = { ++ runAtMillis: runAtMillis, ++ funcToCall: f, ++ recurring: recurring, ++ params: params, ++ timeoutKey: timeoutKey, ++ millis: millis ++ }; ++ ++ if (runAtMillis in scheduledFunctions) { ++ scheduledFunctions[runAtMillis].push(funcToSchedule); ++ } else { ++ scheduledFunctions[runAtMillis] = [funcToSchedule]; ++ scheduledLookup.push(runAtMillis); ++ scheduledLookup.sort(function(a, b) { ++ return a - b; ++ }); ++ } ++ ++ return timeoutKey; ++ }; ++ ++ self.removeFunctionWithId = function(timeoutKey) { ++ deletedKeys.push(timeoutKey); ++ ++ for (var runAtMillis in scheduledFunctions) { ++ var funcs = scheduledFunctions[runAtMillis]; ++ var i = indexOfFirstToPass(funcs, function(func) { ++ return func.timeoutKey === timeoutKey; ++ }); ++ ++ if (i > -1) { ++ if (funcs.length === 1) { ++ delete scheduledFunctions[runAtMillis]; ++ deleteFromLookup(runAtMillis); ++ } else { ++ funcs.splice(i, 1); ++ } ++ ++ // intervals get rescheduled when executed, so there's never more ++ // than a single scheduled function with a given timeoutKey ++ break; ++ } ++ } ++ }; ++ ++ return self; ++ ++ function indexOfFirstToPass(array, testFn) { ++ var index = -1; ++ ++ for (var i = 0; i < array.length; ++i) { ++ if (testFn(array[i])) { ++ index = i; ++ break; ++ } ++ } ++ ++ return index; ++ } ++ ++ function deleteFromLookup(key) { ++ var value = Number(key); ++ var i = indexOfFirstToPass(scheduledLookup, function(millis) { ++ return millis === value; ++ }); ++ ++ if (i > -1) { ++ scheduledLookup.splice(i, 1); ++ } ++ } ++ ++ function reschedule(scheduledFn) { ++ self.scheduleFunction( ++ scheduledFn.funcToCall, ++ scheduledFn.millis, ++ scheduledFn.params, ++ true, ++ scheduledFn.timeoutKey, ++ scheduledFn.runAtMillis + scheduledFn.millis ++ ); ++ } ++ ++ function forEachFunction(funcsToRun, callback) { ++ for (var i = 0; i < funcsToRun.length; ++i) { ++ callback(funcsToRun[i]); ++ } ++ } ++ ++ function runScheduledFunctions(endTime, tickDate) { ++ tickDate = tickDate || function() {}; ++ if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { ++ tickDate(endTime - currentTime); ++ return; ++ } ++ ++ do { ++ deletedKeys = []; ++ var newCurrentTime = scheduledLookup.shift(); ++ tickDate(newCurrentTime - currentTime); ++ ++ currentTime = newCurrentTime; ++ ++ var funcsToRun = scheduledFunctions[currentTime]; ++ ++ delete scheduledFunctions[currentTime]; ++ ++ forEachFunction(funcsToRun, function(funcToRun) { ++ if (funcToRun.recurring) { ++ reschedule(funcToRun); ++ } ++ }); ++ ++ forEachFunction(funcsToRun, function(funcToRun) { ++ if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) { ++ // skip a timeoutKey deleted whilst we were running ++ return; ++ } ++ funcToRun.funcToCall.apply(null, funcToRun.params || []); ++ }); ++ deletedKeys = []; ++ } while ( ++ scheduledLookup.length > 0 && ++ // checking first if we're out of time prevents setTimeout(0) ++ // scheduled in a funcToRun from forcing an extra iteration ++ currentTime !== endTime && ++ scheduledLookup[0] <= endTime ++ ); ++ ++ // ran out of functions to call, but still time left on the clock ++ if (currentTime !== endTime) { ++ tickDate(endTime - currentTime); ++ } ++ } ++ } ++ ++ return DelayedFunctionScheduler; ++}; ++ ++getJasmineRequireObj().errors = function() { ++ function ExpectationFailed() {} ++ ++ ExpectationFailed.prototype = new Error(); ++ ExpectationFailed.prototype.constructor = ExpectationFailed; ++ ++ return { ++ ExpectationFailed: ExpectationFailed ++ }; ++}; ++ ++getJasmineRequireObj().ExceptionFormatter = function(j$) { ++ var ignoredProperties = [ ++ 'name', ++ 'message', ++ 'stack', ++ 'fileName', ++ 'sourceURL', ++ 'line', ++ 'lineNumber', ++ 'column', ++ 'description', ++ 'jasmineMessage' ++ ]; ++ ++ function ExceptionFormatter(options) { ++ var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile(); ++ this.message = function(error) { ++ var message = ''; ++ ++ if (error.jasmineMessage) { ++ message += error.jasmineMessage; ++ } else if (error.name && error.message) { ++ message += error.name + ': ' + error.message; ++ } else if (error.message) { ++ message += error.message; ++ } else { ++ message += error.toString() + ' thrown'; ++ } ++ ++ if (error.fileName || error.sourceURL) { ++ message += ' in ' + (error.fileName || error.sourceURL); ++ } ++ ++ if (error.line || error.lineNumber) { ++ message += ' (line ' + (error.line || error.lineNumber) + ')'; ++ } ++ ++ return message; ++ }; ++ ++ this.stack = function(error) { ++ if (!error || !error.stack) { ++ return null; ++ } ++ ++ var stackTrace = new j$.StackTrace(error); ++ var lines = filterJasmine(stackTrace); ++ var result = ''; ++ ++ if (stackTrace.message) { ++ lines.unshift(stackTrace.message); ++ } ++ ++ result += formatProperties(error); ++ result += lines.join('\n'); ++ ++ return result; ++ }; ++ ++ function filterJasmine(stackTrace) { ++ var result = [], ++ jasmineMarker = ++ stackTrace.style === 'webkit' ? '' : ' at '; ++ ++ stackTrace.frames.forEach(function(frame) { ++ if (frame.file !== jasmineFile) { ++ result.push(frame.raw); ++ } else if (result[result.length - 1] !== jasmineMarker) { ++ result.push(jasmineMarker); ++ } ++ }); ++ ++ return result; ++ } ++ ++ function formatProperties(error) { ++ if (!(error instanceof Object)) { ++ return; ++ } ++ ++ var result = {}; ++ var empty = true; ++ ++ for (var prop in error) { ++ if (j$.util.arrayContains(ignoredProperties, prop)) { ++ continue; ++ } ++ result[prop] = error[prop]; ++ empty = false; ++ } ++ ++ if (!empty) { ++ return 'error properties: ' + j$.pp(result) + '\n'; ++ } ++ ++ return ''; ++ } ++ } ++ ++ return ExceptionFormatter; ++}; ++ ++getJasmineRequireObj().Expectation = function(j$) { ++ /** ++ * Matchers that come with Jasmine out of the box. ++ * @namespace matchers ++ */ ++ function Expectation(options) { ++ this.expector = new j$.Expector(options); ++ ++ var customMatchers = options.customMatchers || {}; ++ for (var matcherName in customMatchers) { ++ this[matcherName] = wrapSyncCompare( ++ matcherName, ++ customMatchers[matcherName] ++ ); ++ } ++ } ++ ++ /** ++ * Add some context for an {@link expect} ++ * @function ++ * @name matchers#withContext ++ * @since 3.3.0 ++ * @param {String} message - Additional context to show when the matcher fails ++ * @return {matchers} ++ */ ++ Expectation.prototype.withContext = function withContext(message) { ++ return addFilter(this, new ContextAddingFilter(message)); ++ }; ++ ++ /** ++ * Invert the matcher following this {@link expect} ++ * @member ++ * @name matchers#not ++ * @since 1.3.0 ++ * @type {matchers} ++ * @example ++ * expect(something).not.toBe(true); ++ */ ++ Object.defineProperty(Expectation.prototype, 'not', { ++ get: function() { ++ return addFilter(this, syncNegatingFilter); ++ } ++ }); ++ ++ /** ++ * Asynchronous matchers that operate on an actual value which is a promise, ++ * and return a promise. ++ * ++ * Most async matchers will wait indefinitely for the promise to be resolved ++ * or rejected, resulting in a spec timeout if that never happens. If you ++ * expect that the promise will already be resolved or rejected at the time ++ * the matcher is called, you can use the {@link async-matchers#already} ++ * modifier to get a faster failure with a more helpful message. ++ * ++ * Note: Specs must await the result of each async matcher, return the ++ * promise returned by the matcher, or return a promise that's derived from ++ * the one returned by the matcher. Otherwise the matcher will not be ++ * evaluated before the spec completes. ++ * ++ * @example ++ * // Good ++ * await expectAsync(aPromise).toBeResolved(); ++ * @example ++ * // Good ++ * return expectAsync(aPromise).toBeResolved(); ++ * @example ++ * // Good ++ * return expectAsync(aPromise).toBeResolved() ++ * .then(function() { ++ * // more spec code ++ * }); ++ * @example ++ * // Bad ++ * expectAsync(aPromise).toBeResolved(); ++ * @namespace async-matchers ++ */ ++ function AsyncExpectation(options) { ++ var global = options.global || j$.getGlobal(); ++ this.expector = new j$.Expector(options); ++ ++ if (!global.Promise) { ++ throw new Error( ++ 'expectAsync is unavailable because the environment does not support promises.' ++ ); ++ } ++ ++ var customAsyncMatchers = options.customAsyncMatchers || {}; ++ for (var matcherName in customAsyncMatchers) { ++ this[matcherName] = wrapAsyncCompare( ++ matcherName, ++ customAsyncMatchers[matcherName] ++ ); ++ } ++ } ++ ++ /** ++ * Add some context for an {@link expectAsync} ++ * @function ++ * @name async-matchers#withContext ++ * @since 3.3.0 ++ * @param {String} message - Additional context to show when the async matcher fails ++ * @return {async-matchers} ++ */ ++ AsyncExpectation.prototype.withContext = function withContext(message) { ++ return addFilter(this, new ContextAddingFilter(message)); ++ }; ++ ++ /** ++ * Invert the matcher following this {@link expectAsync} ++ * @member ++ * @name async-matchers#not ++ * @type {async-matchers} ++ * @example ++ * await expectAsync(myPromise).not.toBeResolved(); ++ * @example ++ * return expectAsync(myPromise).not.toBeResolved(); ++ */ ++ Object.defineProperty(AsyncExpectation.prototype, 'not', { ++ get: function() { ++ return addFilter(this, asyncNegatingFilter); ++ } ++ }); ++ ++ /** ++ * Fail as soon as possible if the actual is pending. ++ * Otherwise evaluate the matcher. ++ * @member ++ * @name async-matchers#already ++ * @since 3.8.0 ++ * @type {async-matchers} ++ * @example ++ * await expectAsync(myPromise).already.toBeResolved(); ++ * @example ++ * return expectAsync(myPromise).already.toBeResolved(); ++ */ ++ Object.defineProperty(AsyncExpectation.prototype, 'already', { ++ get: function() { ++ return addFilter(this, expectSettledPromiseFilter); ++ } ++ }); ++ ++ function wrapSyncCompare(name, matcherFactory) { ++ return function() { ++ var result = this.expector.compare(name, matcherFactory, arguments); ++ this.expector.processResult(result); ++ }; ++ } ++ ++ function wrapAsyncCompare(name, matcherFactory) { ++ return function() { ++ var self = this; ++ ++ // Capture the call stack here, before we go async, so that it will contain ++ // frames that are relevant to the user instead of just parts of Jasmine. ++ var errorForStack = j$.util.errorWithStack(); ++ ++ return this.expector ++ .compare(name, matcherFactory, arguments) ++ .then(function(result) { ++ self.expector.processResult(result, errorForStack); ++ }); ++ }; ++ } ++ ++ function addCoreMatchers(prototype, matchers, wrapper) { ++ for (var matcherName in matchers) { ++ var matcher = matchers[matcherName]; ++ prototype[matcherName] = wrapper(matcherName, matcher); ++ } ++ } ++ ++ function addFilter(source, filter) { ++ var result = Object.create(source); ++ result.expector = source.expector.addFilter(filter); ++ return result; ++ } ++ ++ function negatedFailureMessage(result, matcherName, args, matchersUtil) { ++ if (result.message) { ++ if (j$.isFunction_(result.message)) { ++ return result.message(); ++ } else { ++ return result.message; ++ } ++ } ++ ++ args = args.slice(); ++ args.unshift(true); ++ args.unshift(matcherName); ++ return matchersUtil.buildFailureMessage.apply(matchersUtil, args); ++ } ++ ++ function negate(result) { ++ result.pass = !result.pass; ++ return result; ++ } ++ ++ var syncNegatingFilter = { ++ selectComparisonFunc: function(matcher) { ++ function defaultNegativeCompare() { ++ return negate(matcher.compare.apply(null, arguments)); ++ } ++ ++ return matcher.negativeCompare || defaultNegativeCompare; ++ }, ++ buildFailureMessage: negatedFailureMessage ++ }; ++ ++ var asyncNegatingFilter = { ++ selectComparisonFunc: function(matcher) { ++ function defaultNegativeCompare() { ++ return matcher.compare.apply(this, arguments).then(negate); ++ } ++ ++ return matcher.negativeCompare || defaultNegativeCompare; ++ }, ++ buildFailureMessage: negatedFailureMessage ++ }; ++ ++ var expectSettledPromiseFilter = { ++ selectComparisonFunc: function(matcher) { ++ return function(actual) { ++ var matcherArgs = arguments; ++ ++ return j$.isPending_(actual).then(function(isPending) { ++ if (isPending) { ++ return { ++ pass: false, ++ message: ++ 'Expected a promise to be settled (via ' + ++ 'expectAsync(...).already) but it was pending.' ++ }; ++ } else { ++ return matcher.compare.apply(null, matcherArgs); ++ } ++ }); ++ }; ++ } ++ }; ++ ++ function ContextAddingFilter(message) { ++ this.message = message; ++ } ++ ++ ContextAddingFilter.prototype.modifyFailureMessage = function(msg) { ++ var nl = msg.indexOf('\n'); ++ ++ if (nl === -1) { ++ return this.message + ': ' + msg; ++ } else { ++ return this.message + ':\n' + indent(msg); ++ } ++ }; ++ ++ function indent(s) { ++ return s.replace(/^/gm, ' '); ++ } ++ ++ return { ++ factory: function(options) { ++ return new Expectation(options || {}); ++ }, ++ addCoreMatchers: function(matchers) { ++ addCoreMatchers(Expectation.prototype, matchers, wrapSyncCompare); ++ }, ++ asyncFactory: function(options) { ++ return new AsyncExpectation(options || {}); ++ }, ++ addAsyncCoreMatchers: function(matchers) { ++ addCoreMatchers(AsyncExpectation.prototype, matchers, wrapAsyncCompare); ++ } ++ }; ++}; ++ ++getJasmineRequireObj().ExpectationFilterChain = function() { ++ function ExpectationFilterChain(maybeFilter, prev) { ++ this.filter_ = maybeFilter; ++ this.prev_ = prev; ++ } ++ ++ ExpectationFilterChain.prototype.addFilter = function(filter) { ++ return new ExpectationFilterChain(filter, this); ++ }; ++ ++ ExpectationFilterChain.prototype.selectComparisonFunc = function(matcher) { ++ return this.callFirst_('selectComparisonFunc', arguments).result; ++ }; ++ ++ ExpectationFilterChain.prototype.buildFailureMessage = function( ++ result, ++ matcherName, ++ args, ++ matchersUtil ++ ) { ++ return this.callFirst_('buildFailureMessage', arguments).result; ++ }; ++ ++ ExpectationFilterChain.prototype.modifyFailureMessage = function(msg) { ++ var result = this.callFirst_('modifyFailureMessage', arguments).result; ++ return result || msg; ++ }; ++ ++ ExpectationFilterChain.prototype.callFirst_ = function(fname, args) { ++ var prevResult; ++ ++ if (this.prev_) { ++ prevResult = this.prev_.callFirst_(fname, args); ++ ++ if (prevResult.found) { ++ return prevResult; ++ } ++ } ++ ++ if (this.filter_ && this.filter_[fname]) { ++ return { ++ found: true, ++ result: this.filter_[fname].apply(this.filter_, args) ++ }; ++ } ++ ++ return { found: false }; ++ }; ++ ++ return ExpectationFilterChain; ++}; ++ ++//TODO: expectation result may make more sense as a presentation of an expectation. ++getJasmineRequireObj().buildExpectationResult = function(j$) { ++ function buildExpectationResult(options) { ++ var messageFormatter = options.messageFormatter || function() {}, ++ stackFormatter = options.stackFormatter || function() {}; ++ ++ /** ++ * @typedef Expectation ++ * @property {String} matcherName - The name of the matcher that was executed for this expectation. ++ * @property {String} message - The failure message for the expectation. ++ * @property {String} stack - The stack trace for the failure if available. ++ * @property {Boolean} passed - Whether the expectation passed or failed. ++ * @property {Object} expected - If the expectation failed, what was the expected value. ++ * @property {Object} actual - If the expectation failed, what actual value was produced. ++ */ ++ var result = { ++ matcherName: options.matcherName, ++ message: message(), ++ stack: stack(), ++ passed: options.passed ++ }; ++ ++ if (!result.passed) { ++ result.expected = options.expected; ++ result.actual = options.actual; ++ ++ if (options.error && !j$.isString_(options.error)) { ++ if ('code' in options.error) { ++ result.code = options.error.code; ++ } ++ ++ if ( ++ options.error.code === 'ERR_ASSERTION' && ++ options.expected === '' && ++ options.actual === '' ++ ) { ++ result.expected = options.error.expected; ++ result.actual = options.error.actual; ++ result.matcherName = 'assert ' + options.error.operator; ++ } ++ } ++ } ++ ++ return result; ++ ++ function message() { ++ if (options.passed) { ++ return 'Passed.'; ++ } else if (options.message) { ++ return options.message; ++ } else if (options.error) { ++ return messageFormatter(options.error); ++ } ++ return ''; ++ } ++ ++ function stack() { ++ if (options.passed) { ++ return ''; ++ } ++ ++ var error = options.error; ++ if (!error) { ++ if (options.errorForStack) { ++ error = options.errorForStack; ++ } else if (options.stack) { ++ error = options; ++ } else { ++ try { ++ throw new Error(message()); ++ } catch (e) { ++ error = e; ++ } ++ } ++ } ++ return stackFormatter(error); ++ } ++ } ++ ++ return buildExpectationResult; ++}; ++ ++getJasmineRequireObj().Expector = function(j$) { ++ function Expector(options) { ++ this.matchersUtil = options.matchersUtil || { ++ buildFailureMessage: function() {} ++ }; ++ this.customEqualityTesters = options.customEqualityTesters || []; ++ this.actual = options.actual; ++ this.addExpectationResult = options.addExpectationResult || function() {}; ++ this.filters = new j$.ExpectationFilterChain(); ++ } ++ ++ Expector.prototype.instantiateMatcher = function( ++ matcherName, ++ matcherFactory, ++ args ++ ) { ++ this.matcherName = matcherName; ++ this.args = Array.prototype.slice.call(args, 0); ++ this.expected = this.args.slice(0); ++ ++ this.args.unshift(this.actual); ++ ++ var matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters); ++ var comparisonFunc = this.filters.selectComparisonFunc(matcher); ++ return comparisonFunc || matcher.compare; ++ }; ++ ++ Expector.prototype.buildMessage = function(result) { ++ var self = this; ++ ++ if (result.pass) { ++ return ''; ++ } ++ ++ var msg = this.filters.buildFailureMessage( ++ result, ++ this.matcherName, ++ this.args, ++ this.matchersUtil, ++ defaultMessage ++ ); ++ return this.filters.modifyFailureMessage(msg || defaultMessage()); ++ ++ function defaultMessage() { ++ if (!result.message) { ++ var args = self.args.slice(); ++ args.unshift(false); ++ args.unshift(self.matcherName); ++ return self.matchersUtil.buildFailureMessage.apply( ++ self.matchersUtil, ++ args ++ ); ++ } else if (j$.isFunction_(result.message)) { ++ return result.message(); ++ } else { ++ return result.message; ++ } ++ } ++ }; ++ ++ Expector.prototype.compare = function(matcherName, matcherFactory, args) { ++ var matcherCompare = this.instantiateMatcher( ++ matcherName, ++ matcherFactory, ++ args ++ ); ++ return matcherCompare.apply(null, this.args); ++ }; ++ ++ Expector.prototype.addFilter = function(filter) { ++ var result = Object.create(this); ++ result.filters = this.filters.addFilter(filter); ++ return result; ++ }; ++ ++ Expector.prototype.processResult = function(result, errorForStack) { ++ var message = this.buildMessage(result); ++ ++ if (this.expected.length === 1) { ++ this.expected = this.expected[0]; ++ } ++ ++ this.addExpectationResult(result.pass, { ++ matcherName: this.matcherName, ++ passed: result.pass, ++ message: message, ++ error: errorForStack ? undefined : result.error, ++ errorForStack: errorForStack || undefined, ++ actual: this.actual, ++ expected: this.expected // TODO: this may need to be arrayified/sliced ++ }); ++ }; ++ ++ return Expector; ++}; ++ ++getJasmineRequireObj().formatErrorMsg = function() { ++ function generateErrorMsg(domain, usage) { ++ var usageDefinition = usage ? '\nUsage: ' + usage : ''; ++ ++ return function errorMsg(msg) { ++ return domain + ' : ' + msg + usageDefinition; ++ }; ++ } ++ ++ return generateErrorMsg; ++}; ++ ++getJasmineRequireObj().GlobalErrors = function(j$) { ++ function GlobalErrors(global) { ++ var handlers = []; ++ global = global || j$.getGlobal(); ++ ++ var onerror = function onerror() { ++ var handler = handlers[handlers.length - 1]; ++ ++ if (handler) { ++ handler.apply(null, Array.prototype.slice.call(arguments, 0)); ++ } else { ++ throw arguments[0]; ++ } ++ }; ++ ++ this.originalHandlers = {}; ++ this.jasmineHandlers = {}; ++ this.installOne_ = function installOne_(errorType, jasmineMessage) { ++ function taggedOnError(error) { ++ var substituteMsg; ++ ++ if (j$.isError_(error)) { ++ error.jasmineMessage = jasmineMessage + ': ' + error; ++ } else { ++ if (error) { ++ substituteMsg = jasmineMessage + ': ' + error; ++ } else { ++ substituteMsg = jasmineMessage + ' with no error or message'; ++ } ++ ++ if (errorType === 'unhandledRejection') { ++ substituteMsg += ++ '\n' + ++ '(Tip: to get a useful stack trace, use ' + ++ 'Promise.reject(new Error(...)) instead of Promise.reject(' + ++ (error ? '...' : '') + ++ ').)'; ++ } ++ ++ error = new Error(substituteMsg); ++ } ++ ++ var handler = handlers[handlers.length - 1]; ++ ++ if (handler) { ++ handler(error); ++ } else { ++ throw error; ++ } ++ } ++ ++ this.originalHandlers[errorType] = global.process.listeners(errorType); ++ this.jasmineHandlers[errorType] = taggedOnError; ++ ++ global.process.removeAllListeners(errorType); ++ global.process.on(errorType, taggedOnError); ++ ++ this.uninstall = function uninstall() { ++ var errorTypes = Object.keys(this.originalHandlers); ++ for (var iType = 0; iType < errorTypes.length; iType++) { ++ var errorType = errorTypes[iType]; ++ global.process.removeListener( ++ errorType, ++ this.jasmineHandlers[errorType] ++ ); ++ for (var i = 0; i < this.originalHandlers[errorType].length; i++) { ++ global.process.on(errorType, this.originalHandlers[errorType][i]); ++ } ++ delete this.originalHandlers[errorType]; ++ delete this.jasmineHandlers[errorType]; ++ } ++ }; ++ }; ++ ++ this.install = function install() { ++ if ( ++ global.process && ++ global.process.listeners && ++ j$.isFunction_(global.process.on) ++ ) { ++ this.installOne_('uncaughtException', 'Uncaught exception'); ++ this.installOne_('unhandledRejection', 'Unhandled promise rejection'); ++ } else { ++ var originalHandler = global.onerror; ++ global.onerror = onerror; ++ ++ var browserRejectionHandler = function browserRejectionHandler(event) { ++ if (j$.isError_(event.reason)) { ++ event.reason.jasmineMessage = ++ 'Unhandled promise rejection: ' + event.reason; ++ global.onerror(event.reason); ++ } else { ++ global.onerror('Unhandled promise rejection: ' + event.reason); ++ } ++ }; ++ ++ if (global.addEventListener) { ++ global.addEventListener( ++ 'unhandledrejection', ++ browserRejectionHandler ++ ); ++ } ++ ++ this.uninstall = function uninstall() { ++ global.onerror = originalHandler; ++ if (global.removeEventListener) { ++ global.removeEventListener( ++ 'unhandledrejection', ++ browserRejectionHandler ++ ); ++ } ++ }; ++ } ++ }; ++ ++ this.pushListener = function pushListener(listener) { ++ handlers.push(listener); ++ }; ++ ++ this.popListener = function popListener(listener) { ++ if (!listener) { ++ throw new Error('popListener expects a listener'); ++ } ++ ++ handlers.pop(); ++ }; ++ } ++ ++ return GlobalErrors; ++}; ++ ++/* eslint-disable compat/compat */ ++getJasmineRequireObj().toBePending = function(j$) { ++ /** ++ * Expect a promise to be pending, i.e. the promise is neither resolved nor rejected. ++ * @function ++ * @async ++ * @name async-matchers#toBePending ++ * @since 3.6 ++ * @example ++ * await expectAsync(aPromise).toBePending(); ++ */ ++ return function toBePending() { ++ return { ++ compare: function(actual) { ++ if (!j$.isPromiseLike(actual)) { ++ throw new Error('Expected toBePending to be called on a promise.'); ++ } ++ var want = {}; ++ return Promise.race([actual, Promise.resolve(want)]).then( ++ function(got) { ++ return { pass: want === got }; ++ }, ++ function() { ++ return { pass: false }; ++ } ++ ); ++ } ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().toBeRejected = function(j$) { ++ /** ++ * Expect a promise to be rejected. ++ * @function ++ * @async ++ * @name async-matchers#toBeRejected ++ * @since 3.1.0 ++ * @example ++ * await expectAsync(aPromise).toBeRejected(); ++ * @example ++ * return expectAsync(aPromise).toBeRejected(); ++ */ ++ return function toBeRejected() { ++ return { ++ compare: function(actual) { ++ if (!j$.isPromiseLike(actual)) { ++ throw new Error('Expected toBeRejected to be called on a promise.'); ++ } ++ return actual.then( ++ function() { ++ return { pass: false }; ++ }, ++ function() { ++ return { pass: true }; ++ } ++ ); ++ } ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().toBeRejectedWith = function(j$) { ++ /** ++ * Expect a promise to be rejected with a value equal to the expected, using deep equality comparison. ++ * @function ++ * @async ++ * @name async-matchers#toBeRejectedWith ++ * @since 3.3.0 ++ * @param {Object} expected - Value that the promise is expected to be rejected with ++ * @example ++ * await expectAsync(aPromise).toBeRejectedWith({prop: 'value'}); ++ * @example ++ * return expectAsync(aPromise).toBeRejectedWith({prop: 'value'}); ++ */ ++ return function toBeRejectedWith(matchersUtil) { ++ return { ++ compare: function(actualPromise, expectedValue) { ++ if (!j$.isPromiseLike(actualPromise)) { ++ throw new Error( ++ 'Expected toBeRejectedWith to be called on a promise.' ++ ); ++ } ++ ++ function prefix(passed) { ++ return ( ++ 'Expected a promise ' + ++ (passed ? 'not ' : '') + ++ 'to be rejected with ' + ++ matchersUtil.pp(expectedValue) ++ ); ++ } ++ ++ return actualPromise.then( ++ function() { ++ return { ++ pass: false, ++ message: prefix(false) + ' but it was resolved.' ++ }; ++ }, ++ function(actualValue) { ++ if (matchersUtil.equals(actualValue, expectedValue)) { ++ return { ++ pass: true, ++ message: prefix(true) + '.' ++ }; ++ } else { ++ return { ++ pass: false, ++ message: ++ prefix(false) + ++ ' but it was rejected with ' + ++ matchersUtil.pp(actualValue) + ++ '.' ++ }; ++ } ++ } ++ ); ++ } ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().toBeRejectedWithError = function(j$) { ++ /** ++ * Expect a promise to be rejected with a value matched to the expected ++ * @function ++ * @async ++ * @name async-matchers#toBeRejectedWithError ++ * @since 3.5.0 ++ * @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used. ++ * @param {RegExp|String} [message] - The message that should be set on the thrown `Error` ++ * @example ++ * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, 'Error message'); ++ * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, /Error message/); ++ * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError); ++ * await expectAsync(aPromise).toBeRejectedWithError('Error message'); ++ * return expectAsync(aPromise).toBeRejectedWithError(/Error message/); ++ */ ++ return function toBeRejectedWithError(matchersUtil) { ++ return { ++ compare: function(actualPromise, arg1, arg2) { ++ if (!j$.isPromiseLike(actualPromise)) { ++ throw new Error( ++ 'Expected toBeRejectedWithError to be called on a promise.' ++ ); ++ } ++ ++ var expected = getExpectedFromArgs(arg1, arg2, matchersUtil); ++ ++ return actualPromise.then( ++ function() { ++ return { ++ pass: false, ++ message: 'Expected a promise to be rejected but it was resolved.' ++ }; ++ }, ++ function(actualValue) { ++ return matchError(actualValue, expected, matchersUtil); ++ } ++ ); ++ } ++ }; ++ }; ++ ++ function matchError(actual, expected, matchersUtil) { ++ if (!j$.isError_(actual)) { ++ return fail(expected, 'rejected with ' + matchersUtil.pp(actual)); ++ } ++ ++ if (!(actual instanceof expected.error)) { ++ return fail( ++ expected, ++ 'rejected with type ' + j$.fnNameFor(actual.constructor) ++ ); ++ } ++ ++ var actualMessage = actual.message; ++ ++ if ( ++ actualMessage === expected.message || ++ typeof expected.message === 'undefined' ++ ) { ++ return pass(expected); ++ } ++ ++ if ( ++ expected.message instanceof RegExp && ++ expected.message.test(actualMessage) ++ ) { ++ return pass(expected); ++ } ++ ++ return fail(expected, 'rejected with ' + matchersUtil.pp(actual)); ++ } ++ ++ function pass(expected) { ++ return { ++ pass: true, ++ message: ++ 'Expected a promise not to be rejected with ' + ++ expected.printValue + ++ ', but it was.' ++ }; ++ } ++ ++ function fail(expected, message) { ++ return { ++ pass: false, ++ message: ++ 'Expected a promise to be rejected with ' + ++ expected.printValue + ++ ' but it was ' + ++ message + ++ '.' ++ }; ++ } ++ ++ function getExpectedFromArgs(arg1, arg2, matchersUtil) { ++ var error, message; ++ ++ if (isErrorConstructor(arg1)) { ++ error = arg1; ++ message = arg2; ++ } else { ++ error = Error; ++ message = arg1; ++ } ++ ++ return { ++ error: error, ++ message: message, ++ printValue: ++ j$.fnNameFor(error) + ++ (typeof message === 'undefined' ? '' : ': ' + matchersUtil.pp(message)) ++ }; ++ } ++ ++ function isErrorConstructor(value) { ++ return ( ++ typeof value === 'function' && ++ (value === Error || j$.isError_(value.prototype)) ++ ); ++ } ++}; ++ ++getJasmineRequireObj().toBeResolved = function(j$) { ++ /** ++ * Expect a promise to be resolved. ++ * @function ++ * @async ++ * @name async-matchers#toBeResolved ++ * @since 3.1.0 ++ * @example ++ * await expectAsync(aPromise).toBeResolved(); ++ * @example ++ * return expectAsync(aPromise).toBeResolved(); ++ */ ++ return function toBeResolved(matchersUtil) { ++ return { ++ compare: function(actual) { ++ if (!j$.isPromiseLike(actual)) { ++ throw new Error('Expected toBeResolved to be called on a promise.'); ++ } ++ ++ return actual.then( ++ function() { ++ return { pass: true }; ++ }, ++ function(e) { ++ return { ++ pass: false, ++ message: ++ 'Expected a promise to be resolved but it was ' + ++ 'rejected with ' + ++ matchersUtil.pp(e) + ++ '.' ++ }; ++ } ++ ); ++ } ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().toBeResolvedTo = function(j$) { ++ /** ++ * Expect a promise to be resolved to a value equal to the expected, using deep equality comparison. ++ * @function ++ * @async ++ * @name async-matchers#toBeResolvedTo ++ * @since 3.1.0 ++ * @param {Object} expected - Value that the promise is expected to resolve to ++ * @example ++ * await expectAsync(aPromise).toBeResolvedTo({prop: 'value'}); ++ * @example ++ * return expectAsync(aPromise).toBeResolvedTo({prop: 'value'}); ++ */ ++ return function toBeResolvedTo(matchersUtil) { ++ return { ++ compare: function(actualPromise, expectedValue) { ++ if (!j$.isPromiseLike(actualPromise)) { ++ throw new Error('Expected toBeResolvedTo to be called on a promise.'); ++ } ++ ++ function prefix(passed) { ++ return ( ++ 'Expected a promise ' + ++ (passed ? 'not ' : '') + ++ 'to be resolved to ' + ++ matchersUtil.pp(expectedValue) ++ ); ++ } ++ ++ return actualPromise.then( ++ function(actualValue) { ++ if (matchersUtil.equals(actualValue, expectedValue)) { ++ return { ++ pass: true, ++ message: prefix(true) + '.' ++ }; ++ } else { ++ return { ++ pass: false, ++ message: ++ prefix(false) + ++ ' but it was resolved to ' + ++ matchersUtil.pp(actualValue) + ++ '.' ++ }; ++ } ++ }, ++ function(e) { ++ return { ++ pass: false, ++ message: ++ prefix(false) + ++ ' but it was rejected with ' + ++ matchersUtil.pp(e) + ++ '.' ++ }; ++ } ++ ); ++ } ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().DiffBuilder = function(j$) { ++ return function DiffBuilder(config) { ++ var prettyPrinter = (config || {}).prettyPrinter || j$.makePrettyPrinter(), ++ mismatches = new j$.MismatchTree(), ++ path = new j$.ObjectPath(), ++ actualRoot = undefined, ++ expectedRoot = undefined; ++ ++ return { ++ setRoots: function(actual, expected) { ++ actualRoot = actual; ++ expectedRoot = expected; ++ }, ++ ++ recordMismatch: function(formatter) { ++ mismatches.add(path, formatter); ++ }, ++ ++ getMessage: function() { ++ var messages = []; ++ ++ mismatches.traverse(function(path, isLeaf, formatter) { ++ var actualCustom, ++ expectedCustom, ++ useCustom, ++ derefResult = dereferencePath( ++ path, ++ actualRoot, ++ expectedRoot, ++ prettyPrinter ++ ), ++ actual = derefResult.actual, ++ expected = derefResult.expected; ++ ++ if (formatter) { ++ messages.push(formatter(actual, expected, path, prettyPrinter)); ++ return true; ++ } ++ ++ actualCustom = prettyPrinter.customFormat_(actual); ++ expectedCustom = prettyPrinter.customFormat_(expected); ++ useCustom = !( ++ j$.util.isUndefined(actualCustom) && ++ j$.util.isUndefined(expectedCustom) ++ ); ++ ++ if (useCustom) { ++ messages.push( ++ wrapPrettyPrinted(actualCustom, expectedCustom, path) ++ ); ++ return false; // don't recurse further ++ } ++ ++ if (isLeaf) { ++ messages.push( ++ defaultFormatter(actual, expected, path, prettyPrinter) ++ ); ++ } ++ ++ return true; ++ }); ++ ++ return messages.join('\n'); ++ }, ++ ++ withPath: function(pathComponent, block) { ++ var oldPath = path; ++ path = path.add(pathComponent); ++ block(); ++ path = oldPath; ++ } ++ }; ++ ++ function defaultFormatter(actual, expected, path, prettyPrinter) { ++ return wrapPrettyPrinted( ++ prettyPrinter(actual), ++ prettyPrinter(expected), ++ path ++ ); ++ } ++ ++ function wrapPrettyPrinted(actual, expected, path) { ++ return ( ++ 'Expected ' + ++ path + ++ (path.depth() ? ' = ' : '') + ++ actual + ++ ' to equal ' + ++ expected + ++ '.' ++ ); ++ } ++ }; ++ ++ function dereferencePath(objectPath, actual, expected, pp) { ++ function handleAsymmetricExpected() { ++ if ( ++ j$.isAsymmetricEqualityTester_(expected) && ++ j$.isFunction_(expected.valuesForDiff_) ++ ) { ++ var asymmetricResult = expected.valuesForDiff_(actual, pp); ++ expected = asymmetricResult.self; ++ actual = asymmetricResult.other; ++ } ++ } ++ ++ var i; ++ handleAsymmetricExpected(); ++ ++ for (i = 0; i < objectPath.components.length; i++) { ++ actual = actual[objectPath.components[i]]; ++ expected = expected[objectPath.components[i]]; ++ handleAsymmetricExpected(); ++ } ++ ++ return { actual: actual, expected: expected }; ++ } ++}; ++ ++getJasmineRequireObj().MatchersUtil = function(j$) { ++ // TODO: convert all uses of j$.pp to use the injected pp ++ ++ /** ++ * @class MatchersUtil ++ * @classdesc Utilities for use in implementing matchers.
++ * _Note:_ Do not construct this directly. Jasmine will construct one and ++ * pass it to matchers and asymmetric equality testers. ++ * @hideconstructor ++ */ ++ function MatchersUtil(options) { ++ options = options || {}; ++ this.customTesters_ = options.customTesters || []; ++ /** ++ * Formats a value for use in matcher failure messages and similar contexts, ++ * taking into account the current set of custom value formatters. ++ * @function ++ * @name MatchersUtil#pp ++ * @since 3.6.0 ++ * @param {*} value The value to pretty-print ++ * @return {string} The pretty-printed value ++ */ ++ this.pp = options.pp || function() {}; ++ } ++ ++ /** ++ * Determines whether `haystack` contains `needle`, using the same comparison ++ * logic as {@link MatchersUtil#equals}. ++ * @function ++ * @name MatchersUtil#contains ++ * @since 2.0.0 ++ * @param {*} haystack The collection to search ++ * @param {*} needle The value to search for ++ * @param [customTesters] An array of custom equality testers ++ * @returns {boolean} True if `needle` was found in `haystack` ++ */ ++ MatchersUtil.prototype.contains = function(haystack, needle, customTesters) { ++ if (j$.isSet(haystack)) { ++ return haystack.has(needle); ++ } ++ ++ if ( ++ Object.prototype.toString.apply(haystack) === '[object Array]' || ++ (!!haystack && !haystack.indexOf) ++ ) { ++ for (var i = 0; i < haystack.length; i++) { ++ if (this.equals(haystack[i], needle, customTesters)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ return !!haystack && haystack.indexOf(needle) >= 0; ++ }; ++ ++ MatchersUtil.prototype.buildFailureMessage = function() { ++ var self = this; ++ var args = Array.prototype.slice.call(arguments, 0), ++ matcherName = args[0], ++ isNot = args[1], ++ actual = args[2], ++ expected = args.slice(3), ++ englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { ++ return ' ' + s.toLowerCase(); ++ }); ++ ++ var message = ++ 'Expected ' + ++ self.pp(actual) + ++ (isNot ? ' not ' : ' ') + ++ englishyPredicate; ++ ++ if (expected.length > 0) { ++ for (var i = 0; i < expected.length; i++) { ++ if (i > 0) { ++ message += ','; ++ } ++ message += ' ' + self.pp(expected[i]); ++ } ++ } ++ ++ return message + '.'; ++ }; ++ ++ MatchersUtil.prototype.asymmetricDiff_ = function( ++ a, ++ b, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ) { ++ if (j$.isFunction_(b.valuesForDiff_)) { ++ var values = b.valuesForDiff_(a, this.pp); ++ this.eq_( ++ values.other, ++ values.self, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ); ++ } else { ++ diffBuilder.recordMismatch(); ++ } ++ }; ++ ++ MatchersUtil.prototype.asymmetricMatch_ = function( ++ a, ++ b, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ) { ++ var asymmetricA = j$.isAsymmetricEqualityTester_(a), ++ asymmetricB = j$.isAsymmetricEqualityTester_(b), ++ shim, ++ result; ++ ++ if (asymmetricA === asymmetricB) { ++ return undefined; ++ } ++ ++ shim = j$.asymmetricEqualityTesterArgCompatShim(this, customTesters); ++ ++ if (asymmetricA) { ++ result = a.asymmetricMatch(b, shim); ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ } ++ ++ if (asymmetricB) { ++ result = b.asymmetricMatch(a, shim); ++ if (!result) { ++ this.asymmetricDiff_(a, b, aStack, bStack, customTesters, diffBuilder); ++ } ++ return result; ++ } ++ }; ++ ++ /** ++ * Determines whether two values are deeply equal to each other. ++ * @function ++ * @name MatchersUtil#equals ++ * @since 2.0.0 ++ * @param {*} a The first value to compare ++ * @param {*} b The second value to compare ++ * @param [customTesters] An array of custom equality testers ++ * @returns {boolean} True if the values are equal ++ */ ++ MatchersUtil.prototype.equals = function( ++ a, ++ b, ++ customTestersOrDiffBuilder, ++ diffBuilderOrNothing ++ ) { ++ var customTesters, diffBuilder; ++ ++ if (isDiffBuilder(customTestersOrDiffBuilder)) { ++ diffBuilder = customTestersOrDiffBuilder; ++ } else { ++ customTesters = customTestersOrDiffBuilder; ++ diffBuilder = diffBuilderOrNothing; ++ } ++ ++ customTesters = customTesters || this.customTesters_; ++ diffBuilder = diffBuilder || j$.NullDiffBuilder(); ++ diffBuilder.setRoots(a, b); ++ ++ return this.eq_(a, b, [], [], customTesters, diffBuilder); ++ }; ++ ++ // Equality function lovingly adapted from isEqual in ++ // [Underscore](http://underscorejs.org) ++ MatchersUtil.prototype.eq_ = function( ++ a, ++ b, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ) { ++ var result = true, ++ self = this, ++ i; ++ ++ var asymmetricResult = this.asymmetricMatch_( ++ a, ++ b, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ); ++ if (!j$.util.isUndefined(asymmetricResult)) { ++ return asymmetricResult; ++ } ++ ++ for (i = 0; i < customTesters.length; i++) { ++ var customTesterResult = customTesters[i](a, b); ++ if (!j$.util.isUndefined(customTesterResult)) { ++ if (!customTesterResult) { ++ diffBuilder.recordMismatch(); ++ } ++ return customTesterResult; ++ } ++ } ++ ++ if (a instanceof Error && b instanceof Error) { ++ result = a.message == b.message; ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ } ++ ++ // Identical objects are equal. `0 === -0`, but they aren't identical. ++ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). ++ if (a === b) { ++ result = a !== 0 || 1 / a == 1 / b; ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ } ++ // A strict comparison is necessary because `null == undefined`. ++ if (a === null || b === null) { ++ result = a === b; ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ } ++ var className = Object.prototype.toString.call(a); ++ if (className != Object.prototype.toString.call(b)) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ switch (className) { ++ // Strings, numbers, dates, and booleans are compared by value. ++ case '[object String]': ++ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is ++ // equivalent to `new String("5")`. ++ result = a == String(b); ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ case '[object Number]': ++ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for ++ // other numeric values. ++ result = ++ a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b; ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ case '[object Date]': ++ case '[object Boolean]': ++ // Coerce dates and booleans to numeric primitive values. Dates are compared by their ++ // millisecond representations. Note that invalid dates with millisecond representations ++ // of `NaN` are not equivalent. ++ result = +a == +b; ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ case '[object ArrayBuffer]': ++ // If we have an instance of ArrayBuffer the Uint8Array ctor ++ // will be defined as well ++ return self.eq_( ++ new Uint8Array(a), // eslint-disable-line compat/compat ++ new Uint8Array(b), // eslint-disable-line compat/compat ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ); ++ // RegExps are compared by their source patterns and flags. ++ case '[object RegExp]': ++ return ( ++ a.source == b.source && ++ a.global == b.global && ++ a.multiline == b.multiline && ++ a.ignoreCase == b.ignoreCase ++ ); ++ } ++ if (typeof a != 'object' || typeof b != 'object') { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ ++ var aIsDomNode = j$.isDomNode(a); ++ var bIsDomNode = j$.isDomNode(b); ++ if (aIsDomNode && bIsDomNode) { ++ // At first try to use DOM3 method isEqualNode ++ result = a.isEqualNode(b); ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ } ++ return result; ++ } ++ if (aIsDomNode || bIsDomNode) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ ++ var aIsPromise = j$.isPromise(a); ++ var bIsPromise = j$.isPromise(b); ++ if (aIsPromise && bIsPromise) { ++ return a === b; ++ } ++ ++ // Assume equality for cyclic structures. The algorithm for detecting cyclic ++ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. ++ var length = aStack.length; ++ while (length--) { ++ // Linear search. Performance is inversely proportional to the number of ++ // unique nested structures. ++ if (aStack[length] == a) { ++ return bStack[length] == b; ++ } ++ } ++ // Add the first object to the stack of traversed objects. ++ aStack.push(a); ++ bStack.push(b); ++ var size = 0; ++ // Recursively compare objects and arrays. ++ // Compare array lengths to determine if a deep comparison is necessary. ++ if (className == '[object Array]') { ++ var aLength = a.length; ++ var bLength = b.length; ++ ++ diffBuilder.withPath('length', function() { ++ if (aLength !== bLength) { ++ diffBuilder.recordMismatch(); ++ result = false; ++ } ++ }); ++ ++ for (i = 0; i < aLength || i < bLength; i++) { ++ diffBuilder.withPath(i, function() { ++ if (i >= bLength) { ++ diffBuilder.recordMismatch( ++ actualArrayIsLongerFormatter.bind(null, self.pp) ++ ); ++ result = false; ++ } else { ++ result = ++ self.eq_( ++ i < aLength ? a[i] : void 0, ++ i < bLength ? b[i] : void 0, ++ aStack, ++ bStack, ++ customTesters, ++ diffBuilder ++ ) && result; ++ } ++ }); ++ } ++ if (!result) { ++ return false; ++ } ++ } else if (j$.isMap(a) && j$.isMap(b)) { ++ if (a.size != b.size) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ ++ var keysA = []; ++ var keysB = []; ++ a.forEach(function(valueA, keyA) { ++ keysA.push(keyA); ++ }); ++ b.forEach(function(valueB, keyB) { ++ keysB.push(keyB); ++ }); ++ ++ // For both sets of keys, check they map to equal values in both maps. ++ // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys. ++ var mapKeys = [keysA, keysB]; ++ var cmpKeys = [keysB, keysA]; ++ var mapIter, mapKey, mapValueA, mapValueB; ++ var cmpIter, cmpKey; ++ for (i = 0; result && i < mapKeys.length; i++) { ++ mapIter = mapKeys[i]; ++ cmpIter = cmpKeys[i]; ++ ++ for (var j = 0; result && j < mapIter.length; j++) { ++ mapKey = mapIter[j]; ++ cmpKey = cmpIter[j]; ++ mapValueA = a.get(mapKey); ++ ++ // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches, ++ // otherwise explicitly look up the mapKey in the other Map since we want keys with unique ++ // obj identity (that are otherwise equal) to not match. ++ if ( ++ j$.isAsymmetricEqualityTester_(mapKey) || ++ (j$.isAsymmetricEqualityTester_(cmpKey) && ++ this.eq_( ++ mapKey, ++ cmpKey, ++ aStack, ++ bStack, ++ customTesters, ++ j$.NullDiffBuilder() ++ )) ++ ) { ++ mapValueB = b.get(cmpKey); ++ } else { ++ mapValueB = b.get(mapKey); ++ } ++ result = this.eq_( ++ mapValueA, ++ mapValueB, ++ aStack, ++ bStack, ++ customTesters, ++ j$.NullDiffBuilder() ++ ); ++ } ++ } ++ ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ } else if (j$.isSet(a) && j$.isSet(b)) { ++ if (a.size != b.size) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ ++ var valuesA = []; ++ a.forEach(function(valueA) { ++ valuesA.push(valueA); ++ }); ++ var valuesB = []; ++ b.forEach(function(valueB) { ++ valuesB.push(valueB); ++ }); ++ ++ // For both sets, check they are all contained in the other set ++ var setPairs = [[valuesA, valuesB], [valuesB, valuesA]]; ++ var stackPairs = [[aStack, bStack], [bStack, aStack]]; ++ var baseValues, baseValue, baseStack; ++ var otherValues, otherValue, otherStack; ++ var found; ++ var prevStackSize; ++ for (i = 0; result && i < setPairs.length; i++) { ++ baseValues = setPairs[i][0]; ++ otherValues = setPairs[i][1]; ++ baseStack = stackPairs[i][0]; ++ otherStack = stackPairs[i][1]; ++ // For each value in the base set... ++ for (var k = 0; result && k < baseValues.length; k++) { ++ baseValue = baseValues[k]; ++ found = false; ++ // ... test that it is present in the other set ++ for (var l = 0; !found && l < otherValues.length; l++) { ++ otherValue = otherValues[l]; ++ prevStackSize = baseStack.length; ++ // compare by value equality ++ found = this.eq_( ++ baseValue, ++ otherValue, ++ baseStack, ++ otherStack, ++ customTesters, ++ j$.NullDiffBuilder() ++ ); ++ if (!found && prevStackSize !== baseStack.length) { ++ baseStack.splice(prevStackSize); ++ otherStack.splice(prevStackSize); ++ } ++ } ++ result = result && found; ++ } ++ } ++ ++ if (!result) { ++ diffBuilder.recordMismatch(); ++ return false; ++ } ++ } else if (j$.isURL(a) && j$.isURL(b)) { ++ // URLs have no enumrable properties, so the default object comparison ++ // would consider any two URLs to be equal. ++ return a.toString() === b.toString(); ++ } else { ++ // Objects with different constructors are not equivalent, but `Object`s ++ // or `Array`s from different frames are. ++ var aCtor = a.constructor, ++ bCtor = b.constructor; ++ if ( ++ aCtor !== bCtor && ++ isFunction(aCtor) && ++ isFunction(bCtor) && ++ a instanceof aCtor && ++ b instanceof bCtor && ++ !(aCtor instanceof aCtor && bCtor instanceof bCtor) ++ ) { ++ diffBuilder.recordMismatch( ++ constructorsAreDifferentFormatter.bind(null, this.pp) ++ ); ++ return false; ++ } ++ } ++ ++ // Deep compare objects. ++ var aKeys = keys(a, className == '[object Array]'), ++ key; ++ size = aKeys.length; ++ ++ // Ensure that both objects contain the same number of properties before comparing deep equality. ++ if (keys(b, className == '[object Array]').length !== size) { ++ diffBuilder.recordMismatch( ++ objectKeysAreDifferentFormatter.bind(null, this.pp) ++ ); ++ return false; ++ } ++ ++ for (i = 0; i < size; i++) { ++ key = aKeys[i]; ++ // Deep compare each member ++ if (!j$.util.has(b, key)) { ++ diffBuilder.recordMismatch( ++ objectKeysAreDifferentFormatter.bind(null, this.pp) ++ ); ++ result = false; ++ continue; ++ } ++ ++ diffBuilder.withPath(key, function() { ++ if ( ++ !self.eq_(a[key], b[key], aStack, bStack, customTesters, diffBuilder) ++ ) { ++ result = false; ++ } ++ }); ++ } ++ ++ if (!result) { ++ return false; ++ } ++ ++ // Remove the first object from the stack of traversed objects. ++ aStack.pop(); ++ bStack.pop(); ++ ++ return result; ++ }; ++ ++ function keys(obj, isArray) { ++ var allKeys = Object.keys ++ ? Object.keys(obj) ++ : (function(o) { ++ var keys = []; ++ for (var key in o) { ++ if (j$.util.has(o, key)) { ++ keys.push(key); ++ } ++ } ++ return keys; ++ })(obj); ++ ++ if (!isArray) { ++ return allKeys; ++ } ++ ++ if (allKeys.length === 0) { ++ return allKeys; ++ } ++ ++ var extraKeys = []; ++ for (var i = 0; i < allKeys.length; i++) { ++ if (!/^[0-9]+$/.test(allKeys[i])) { ++ extraKeys.push(allKeys[i]); ++ } ++ } ++ ++ return extraKeys; ++ } ++ ++ function isFunction(obj) { ++ return typeof obj === 'function'; ++ } ++ ++ function objectKeysAreDifferentFormatter(pp, actual, expected, path) { ++ var missingProperties = j$.util.objectDifference(expected, actual), ++ extraProperties = j$.util.objectDifference(actual, expected), ++ missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties), ++ extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties), ++ messages = []; ++ ++ if (!path.depth()) { ++ path = 'object'; ++ } ++ ++ if (missingPropertiesMessage.length) { ++ messages.push( ++ 'Expected ' + path + ' to have properties' + missingPropertiesMessage ++ ); ++ } ++ ++ if (extraPropertiesMessage.length) { ++ messages.push( ++ 'Expected ' + path + ' not to have properties' + extraPropertiesMessage ++ ); ++ } ++ ++ return messages.join('\n'); ++ } ++ ++ function constructorsAreDifferentFormatter(pp, actual, expected, path) { ++ if (!path.depth()) { ++ path = 'object'; ++ } ++ ++ return ( ++ 'Expected ' + ++ path + ++ ' to be a kind of ' + ++ j$.fnNameFor(expected.constructor) + ++ ', but was ' + ++ pp(actual) + ++ '.' ++ ); ++ } ++ ++ function actualArrayIsLongerFormatter(pp, actual, expected, path) { ++ return ( ++ 'Unexpected ' + ++ path + ++ (path.depth() ? ' = ' : '') + ++ pp(actual) + ++ ' in array.' ++ ); ++ } ++ ++ function formatKeyValuePairs(pp, obj) { ++ var formatted = ''; ++ for (var key in obj) { ++ formatted += '\n ' + key + ': ' + pp(obj[key]); ++ } ++ return formatted; ++ } ++ ++ function isDiffBuilder(obj) { ++ return obj && typeof obj.recordMismatch === 'function'; ++ } ++ ++ return MatchersUtil; ++}; ++ ++/** ++ * @interface AsymmetricEqualityTester ++ * @classdesc An asymmetric equality tester is an object that can match multiple ++ * objects. Examples include jasmine.any() and jasmine.stringMatching(). Jasmine ++ * includes a number of built-in asymmetric equality testers, such as ++ * {@link jasmine.objectContaining}. User-defined asymmetric equality testers are ++ * also supported. ++ * ++ * Asymmetric equality testers work with any matcher, including user-defined ++ * custom matchers, that uses {@link MatchersUtil#equals} or ++ * {@link MatchersUtil#contains}. ++ * ++ * @example ++ * function numberDivisibleBy(divisor) { ++ * return { ++ * asymmetricMatch: function(n) { ++ * return typeof n === 'number' && n % divisor === 0; ++ * }, ++ * jasmineToString: function() { ++ * return ``; ++ * } ++ * }; ++ * } ++ * ++ * var actual = { ++ * n: 2, ++ * otherFields: "don't care" ++ * }; ++ * ++ * expect(actual).toEqual(jasmine.objectContaining({n: numberDivisibleBy(2)})); ++ * @see custom_asymmetric_equality_testers ++ * @since 2.0.0 ++ */ ++/** ++ * Determines whether a value matches this tester ++ * @function ++ * @name AsymmetricEqualityTester#asymmetricMatch ++ * @param value {any} The value to test ++ * @param matchersUtil {MatchersUtil} utilities for testing equality, etc ++ * @return {Boolean} ++ */ ++/** ++ * Returns a string representation of this tester to use in matcher failure messages ++ * @function ++ * @name AsymmetricEqualityTester#jasmineToString ++ * @param pp {function} Function that takes a value and returns a pretty-printed representation ++ * @return {String} ++ */ ++ ++getJasmineRequireObj().MismatchTree = function(j$) { ++ /* ++ To be able to apply custom object formatters at all possible levels of an ++ object graph, DiffBuilder needs to be able to know not just where the ++ mismatch occurred but also all ancestors of the mismatched value in both ++ the expected and actual object graphs. MismatchTree maintains that context ++ and provides it via the traverse method. ++ */ ++ function MismatchTree(path) { ++ this.path = path || new j$.ObjectPath([]); ++ this.formatter = undefined; ++ this.children = []; ++ this.isMismatch = false; ++ } ++ ++ MismatchTree.prototype.add = function(path, formatter) { ++ var key, child; ++ ++ if (path.depth() === 0) { ++ this.formatter = formatter; ++ this.isMismatch = true; ++ } else { ++ key = path.components[0]; ++ path = path.shift(); ++ child = this.child(key); ++ ++ if (!child) { ++ child = new MismatchTree(this.path.add(key)); ++ this.children.push(child); ++ } ++ ++ child.add(path, formatter); ++ } ++ }; ++ ++ MismatchTree.prototype.traverse = function(visit) { ++ var i, ++ hasChildren = this.children.length > 0; ++ ++ if (this.isMismatch || hasChildren) { ++ if (visit(this.path, !hasChildren, this.formatter)) { ++ for (i = 0; i < this.children.length; i++) { ++ this.children[i].traverse(visit); ++ } ++ } ++ } ++ }; ++ ++ MismatchTree.prototype.child = function(key) { ++ var i, pathEls; ++ ++ for (i = 0; i < this.children.length; i++) { ++ pathEls = this.children[i].path.components; ++ if (pathEls[pathEls.length - 1] === key) { ++ return this.children[i]; ++ } ++ } ++ }; ++ ++ return MismatchTree; ++}; ++ ++getJasmineRequireObj().nothing = function() { ++ /** ++ * {@link expect} nothing explicitly. ++ * @function ++ * @name matchers#nothing ++ * @since 2.8.0 ++ * @example ++ * expect().nothing(); ++ */ ++ function nothing() { ++ return { ++ compare: function() { ++ return { ++ pass: true ++ }; ++ } ++ }; ++ } ++ ++ return nothing; ++}; ++ ++getJasmineRequireObj().NullDiffBuilder = function(j$) { ++ return function() { ++ return { ++ withPath: function(_, block) { ++ block(); ++ }, ++ setRoots: function() {}, ++ recordMismatch: function() {} ++ }; ++ }; ++}; ++ ++getJasmineRequireObj().ObjectPath = function(j$) { ++ function ObjectPath(components) { ++ this.components = components || []; ++ } ++ ++ ObjectPath.prototype.toString = function() { ++ if (this.components.length) { ++ return '$' + map(this.components, formatPropertyAccess).join(''); ++ } else { ++ return ''; ++ } ++ }; ++ ++ ObjectPath.prototype.add = function(component) { ++ return new ObjectPath(this.components.concat([component])); ++ }; ++ ++ ObjectPath.prototype.shift = function() { ++ return new ObjectPath(this.components.slice(1)); ++ }; ++ ++ ObjectPath.prototype.depth = function() { ++ return this.components.length; ++ }; ++ ++ function formatPropertyAccess(prop) { ++ if (typeof prop === 'number') { ++ return '[' + prop + ']'; ++ } ++ ++ if (isValidIdentifier(prop)) { ++ return '.' + prop; ++ } ++ ++ return "['" + prop + "']"; ++ } ++ ++ function map(array, fn) { ++ var results = []; ++ for (var i = 0; i < array.length; i++) { ++ results.push(fn(array[i])); ++ } ++ return results; ++ } ++ ++ function isValidIdentifier(string) { ++ return /^[A-Za-z\$_][A-Za-z0-9\$_]*$/.test(string); ++ } ++ ++ return ObjectPath; ++}; ++ ++getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) { ++ var availableMatchers = [ ++ 'toBePending', ++ 'toBeResolved', ++ 'toBeRejected', ++ 'toBeResolvedTo', ++ 'toBeRejectedWith', ++ 'toBeRejectedWithError' ++ ], ++ matchers = {}; ++ ++ for (var i = 0; i < availableMatchers.length; i++) { ++ var name = availableMatchers[i]; ++ matchers[name] = jRequire[name](j$); ++ } ++ ++ return matchers; ++}; ++ ++getJasmineRequireObj().toBe = function(j$) { ++ /** ++ * {@link expect} the actual value to be `===` to the expected value. ++ * @function ++ * @name matchers#toBe ++ * @since 1.3.0 ++ * @param {Object} expected - The expected value to compare against. ++ * @example ++ * expect(thing).toBe(realThing); ++ */ ++ function toBe(matchersUtil) { ++ var tip = ++ ' Tip: To check for deep equality, use .toEqual() instead of .toBe().'; ++ ++ return { ++ compare: function(actual, expected) { ++ var result = { ++ pass: actual === expected ++ }; ++ ++ if (typeof expected === 'object') { ++ result.message = ++ matchersUtil.buildFailureMessage( ++ 'toBe', ++ result.pass, ++ actual, ++ expected ++ ) + tip; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toBe; ++}; ++ ++getJasmineRequireObj().toBeCloseTo = function() { ++ /** ++ * {@link expect} the actual value to be within a specified precision of the expected value. ++ * @function ++ * @name matchers#toBeCloseTo ++ * @since 1.3.0 ++ * @param {Object} expected - The expected value to compare against. ++ * @param {Number} [precision=2] - The number of decimal points to check. ++ * @example ++ * expect(number).toBeCloseTo(42.2, 3); ++ */ ++ function toBeCloseTo() { ++ return { ++ compare: function(actual, expected, precision) { ++ if (precision !== 0) { ++ precision = precision || 2; ++ } ++ ++ if (expected === null || actual === null) { ++ throw new Error( ++ 'Cannot use toBeCloseTo with null. Arguments evaluated to: ' + ++ 'expect(' + ++ actual + ++ ').toBeCloseTo(' + ++ expected + ++ ').' ++ ); ++ } ++ ++ var pow = Math.pow(10, precision + 1); ++ var delta = Math.abs(expected - actual); ++ var maxDelta = Math.pow(10, -precision) / 2; ++ ++ return { ++ pass: Math.round(delta * pow) <= maxDelta * pow ++ }; ++ } ++ }; ++ } ++ ++ return toBeCloseTo; ++}; ++ ++getJasmineRequireObj().toBeDefined = function() { ++ /** ++ * {@link expect} the actual value to be defined. (Not `undefined`) ++ * @function ++ * @name matchers#toBeDefined ++ * @since 1.3.0 ++ * @example ++ * expect(result).toBeDefined(); ++ */ ++ function toBeDefined() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: void 0 !== actual ++ }; ++ } ++ }; ++ } ++ ++ return toBeDefined; ++}; ++ ++getJasmineRequireObj().toBeFalse = function() { ++ /** ++ * {@link expect} the actual value to be `false`. ++ * @function ++ * @name matchers#toBeFalse ++ * @since 3.5.0 ++ * @example ++ * expect(result).toBeFalse(); ++ */ ++ function toBeFalse() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: actual === false ++ }; ++ } ++ }; ++ } ++ ++ return toBeFalse; ++}; ++ ++getJasmineRequireObj().toBeFalsy = function() { ++ /** ++ * {@link expect} the actual value to be falsy ++ * @function ++ * @name matchers#toBeFalsy ++ * @since 2.0.0 ++ * @example ++ * expect(result).toBeFalsy(); ++ */ ++ function toBeFalsy() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: !actual ++ }; ++ } ++ }; ++ } ++ ++ return toBeFalsy; ++}; ++ ++getJasmineRequireObj().toBeGreaterThan = function() { ++ /** ++ * {@link expect} the actual value to be greater than the expected value. ++ * @function ++ * @name matchers#toBeGreaterThan ++ * @since 2.0.0 ++ * @param {Number} expected - The value to compare against. ++ * @example ++ * expect(result).toBeGreaterThan(3); ++ */ ++ function toBeGreaterThan() { ++ return { ++ compare: function(actual, expected) { ++ return { ++ pass: actual > expected ++ }; ++ } ++ }; ++ } ++ ++ return toBeGreaterThan; ++}; ++ ++getJasmineRequireObj().toBeGreaterThanOrEqual = function() { ++ /** ++ * {@link expect} the actual value to be greater than or equal to the expected value. ++ * @function ++ * @name matchers#toBeGreaterThanOrEqual ++ * @since 2.0.0 ++ * @param {Number} expected - The expected value to compare against. ++ * @example ++ * expect(result).toBeGreaterThanOrEqual(25); ++ */ ++ function toBeGreaterThanOrEqual() { ++ return { ++ compare: function(actual, expected) { ++ return { ++ pass: actual >= expected ++ }; ++ } ++ }; ++ } ++ ++ return toBeGreaterThanOrEqual; ++}; ++ ++getJasmineRequireObj().toBeInstanceOf = function(j$) { ++ var usageError = j$.formatErrorMsg( ++ '', ++ 'expect(value).toBeInstanceOf()' ++ ); ++ ++ /** ++ * {@link expect} the actual to be an instance of the expected class ++ * @function ++ * @name matchers#toBeInstanceOf ++ * @since 3.5.0 ++ * @param {Object} expected - The class or constructor function to check for ++ * @example ++ * expect('foo').toBeInstanceOf(String); ++ * expect(3).toBeInstanceOf(Number); ++ * expect(new Error()).toBeInstanceOf(Error); ++ */ ++ function toBeInstanceOf(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ var actualType = ++ actual && actual.constructor ++ ? j$.fnNameFor(actual.constructor) ++ : matchersUtil.pp(actual), ++ expectedType = expected ++ ? j$.fnNameFor(expected) ++ : matchersUtil.pp(expected), ++ expectedMatcher, ++ pass; ++ ++ try { ++ expectedMatcher = new j$.Any(expected); ++ pass = expectedMatcher.asymmetricMatch(actual); ++ } catch (error) { ++ throw new Error( ++ usageError('Expected value is not a constructor function') ++ ); ++ } ++ ++ if (pass) { ++ return { ++ pass: true, ++ message: ++ 'Expected instance of ' + ++ actualType + ++ ' not to be an instance of ' + ++ expectedType ++ }; ++ } else { ++ return { ++ pass: false, ++ message: ++ 'Expected instance of ' + ++ actualType + ++ ' to be an instance of ' + ++ expectedType ++ }; ++ } ++ } ++ }; ++ } ++ ++ return toBeInstanceOf; ++}; ++ ++getJasmineRequireObj().toBeLessThan = function() { ++ /** ++ * {@link expect} the actual value to be less than the expected value. ++ * @function ++ * @name matchers#toBeLessThan ++ * @since 2.0.0 ++ * @param {Number} expected - The expected value to compare against. ++ * @example ++ * expect(result).toBeLessThan(0); ++ */ ++ function toBeLessThan() { ++ return { ++ compare: function(actual, expected) { ++ return { ++ pass: actual < expected ++ }; ++ } ++ }; ++ } ++ ++ return toBeLessThan; ++}; ++ ++getJasmineRequireObj().toBeLessThanOrEqual = function() { ++ /** ++ * {@link expect} the actual value to be less than or equal to the expected value. ++ * @function ++ * @name matchers#toBeLessThanOrEqual ++ * @since 2.0.0 ++ * @param {Number} expected - The expected value to compare against. ++ * @example ++ * expect(result).toBeLessThanOrEqual(123); ++ */ ++ function toBeLessThanOrEqual() { ++ return { ++ compare: function(actual, expected) { ++ return { ++ pass: actual <= expected ++ }; ++ } ++ }; ++ } ++ ++ return toBeLessThanOrEqual; ++}; ++ ++getJasmineRequireObj().toBeNaN = function(j$) { ++ /** ++ * {@link expect} the actual value to be `NaN` (Not a Number). ++ * @function ++ * @name matchers#toBeNaN ++ * @since 1.3.0 ++ * @example ++ * expect(thing).toBeNaN(); ++ */ ++ function toBeNaN(matchersUtil) { ++ return { ++ compare: function(actual) { ++ var result = { ++ pass: actual !== actual ++ }; ++ ++ if (result.pass) { ++ result.message = 'Expected actual not to be NaN.'; ++ } else { ++ result.message = function() { ++ return 'Expected ' + matchersUtil.pp(actual) + ' to be NaN.'; ++ }; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toBeNaN; ++}; ++ ++getJasmineRequireObj().toBeNegativeInfinity = function(j$) { ++ /** ++ * {@link expect} the actual value to be `-Infinity` (-infinity). ++ * @function ++ * @name matchers#toBeNegativeInfinity ++ * @since 2.6.0 ++ * @example ++ * expect(thing).toBeNegativeInfinity(); ++ */ ++ function toBeNegativeInfinity(matchersUtil) { ++ return { ++ compare: function(actual) { ++ var result = { ++ pass: actual === Number.NEGATIVE_INFINITY ++ }; ++ ++ if (result.pass) { ++ result.message = 'Expected actual not to be -Infinity.'; ++ } else { ++ result.message = function() { ++ return 'Expected ' + matchersUtil.pp(actual) + ' to be -Infinity.'; ++ }; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toBeNegativeInfinity; ++}; ++ ++getJasmineRequireObj().toBeNull = function() { ++ /** ++ * {@link expect} the actual value to be `null`. ++ * @function ++ * @name matchers#toBeNull ++ * @since 1.3.0 ++ * @example ++ * expect(result).toBeNull(); ++ */ ++ function toBeNull() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: actual === null ++ }; ++ } ++ }; ++ } ++ ++ return toBeNull; ++}; ++ ++getJasmineRequireObj().toBePositiveInfinity = function(j$) { ++ /** ++ * {@link expect} the actual value to be `Infinity` (infinity). ++ * @function ++ * @name matchers#toBePositiveInfinity ++ * @since 2.6.0 ++ * @example ++ * expect(thing).toBePositiveInfinity(); ++ */ ++ function toBePositiveInfinity(matchersUtil) { ++ return { ++ compare: function(actual) { ++ var result = { ++ pass: actual === Number.POSITIVE_INFINITY ++ }; ++ ++ if (result.pass) { ++ result.message = 'Expected actual not to be Infinity.'; ++ } else { ++ result.message = function() { ++ return 'Expected ' + matchersUtil.pp(actual) + ' to be Infinity.'; ++ }; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toBePositiveInfinity; ++}; ++ ++getJasmineRequireObj().toBeTrue = function() { ++ /** ++ * {@link expect} the actual value to be `true`. ++ * @function ++ * @name matchers#toBeTrue ++ * @since 3.5.0 ++ * @example ++ * expect(result).toBeTrue(); ++ */ ++ function toBeTrue() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: actual === true ++ }; ++ } ++ }; ++ } ++ ++ return toBeTrue; ++}; ++ ++getJasmineRequireObj().toBeTruthy = function() { ++ /** ++ * {@link expect} the actual value to be truthy. ++ * @function ++ * @name matchers#toBeTruthy ++ * @since 2.0.0 ++ * @example ++ * expect(thing).toBeTruthy(); ++ */ ++ function toBeTruthy() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: !!actual ++ }; ++ } ++ }; ++ } ++ ++ return toBeTruthy; ++}; ++ ++getJasmineRequireObj().toBeUndefined = function() { ++ /** ++ * {@link expect} the actual value to be `undefined`. ++ * @function ++ * @name matchers#toBeUndefined ++ * @since 1.3.0 ++ * @example ++ * expect(result).toBeUndefined(): ++ */ ++ function toBeUndefined() { ++ return { ++ compare: function(actual) { ++ return { ++ pass: void 0 === actual ++ }; ++ } ++ }; ++ } ++ ++ return toBeUndefined; ++}; ++ ++getJasmineRequireObj().toContain = function() { ++ /** ++ * {@link expect} the actual value to contain a specific value. ++ * @function ++ * @name matchers#toContain ++ * @since 2.0.0 ++ * @param {Object} expected - The value to look for. ++ * @example ++ * expect(array).toContain(anElement); ++ * expect(string).toContain(substring); ++ */ ++ function toContain(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ return { ++ pass: matchersUtil.contains(actual, expected) ++ }; ++ } ++ }; ++ } ++ ++ return toContain; ++}; ++ ++getJasmineRequireObj().toEqual = function(j$) { ++ /** ++ * {@link expect} the actual value to be equal to the expected, using deep equality comparison. ++ * @function ++ * @name matchers#toEqual ++ * @since 1.3.0 ++ * @param {Object} expected - Expected value ++ * @example ++ * expect(bigObject).toEqual({"foo": ['bar', 'baz']}); ++ */ ++ function toEqual(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ var result = { ++ pass: false ++ }, ++ diffBuilder = j$.DiffBuilder({ prettyPrinter: matchersUtil.pp }); ++ ++ result.pass = matchersUtil.equals(actual, expected, diffBuilder); ++ ++ // TODO: only set error message if test fails ++ result.message = diffBuilder.getMessage(); ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toEqual; ++}; ++ ++getJasmineRequireObj().toHaveBeenCalled = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toHaveBeenCalled()' ++ ); ++ ++ /** ++ * {@link expect} the actual (a {@link Spy}) to have been called. ++ * @function ++ * @name matchers#toHaveBeenCalled ++ * @since 1.3.0 ++ * @example ++ * expect(mySpy).toHaveBeenCalled(); ++ * expect(mySpy).not.toHaveBeenCalled(); ++ */ ++ function toHaveBeenCalled(matchersUtil) { ++ return { ++ compare: function(actual) { ++ var result = {}; ++ ++ if (!j$.isSpy(actual)) { ++ throw new Error( ++ getErrorMsg( ++ 'Expected a spy, but got ' + matchersUtil.pp(actual) + '.' ++ ) ++ ); ++ } ++ ++ if (arguments.length > 1) { ++ throw new Error( ++ getErrorMsg('Does not take arguments, use toHaveBeenCalledWith') ++ ); ++ } ++ ++ result.pass = actual.calls.any(); ++ ++ result.message = result.pass ++ ? 'Expected spy ' + actual.and.identity + ' not to have been called.' ++ : 'Expected spy ' + actual.and.identity + ' to have been called.'; ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toHaveBeenCalled; ++}; ++ ++getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toHaveBeenCalledBefore()' ++ ); ++ ++ /** ++ * {@link expect} the actual value (a {@link Spy}) to have been called before another {@link Spy}. ++ * @function ++ * @name matchers#toHaveBeenCalledBefore ++ * @since 2.6.0 ++ * @param {Spy} expected - {@link Spy} that should have been called after the `actual` {@link Spy}. ++ * @example ++ * expect(mySpy).toHaveBeenCalledBefore(otherSpy); ++ */ ++ function toHaveBeenCalledBefore(matchersUtil) { ++ return { ++ compare: function(firstSpy, latterSpy) { ++ if (!j$.isSpy(firstSpy)) { ++ throw new Error( ++ getErrorMsg( ++ 'Expected a spy, but got ' + matchersUtil.pp(firstSpy) + '.' ++ ) ++ ); ++ } ++ if (!j$.isSpy(latterSpy)) { ++ throw new Error( ++ getErrorMsg( ++ 'Expected a spy, but got ' + matchersUtil.pp(latterSpy) + '.' ++ ) ++ ); ++ } ++ ++ var result = { pass: false }; ++ ++ if (!firstSpy.calls.count()) { ++ result.message = ++ 'Expected spy ' + firstSpy.and.identity + ' to have been called.'; ++ return result; ++ } ++ if (!latterSpy.calls.count()) { ++ result.message = ++ 'Expected spy ' + latterSpy.and.identity + ' to have been called.'; ++ return result; ++ } ++ ++ var latest1stSpyCall = firstSpy.calls.mostRecent().invocationOrder; ++ var first2ndSpyCall = latterSpy.calls.first().invocationOrder; ++ ++ result.pass = latest1stSpyCall < first2ndSpyCall; ++ ++ if (result.pass) { ++ result.message = ++ 'Expected spy ' + ++ firstSpy.and.identity + ++ ' to not have been called before spy ' + ++ latterSpy.and.identity + ++ ', but it was'; ++ } else { ++ var first1stSpyCall = firstSpy.calls.first().invocationOrder; ++ var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder; ++ ++ if (first1stSpyCall < first2ndSpyCall) { ++ result.message = ++ 'Expected latest call to spy ' + ++ firstSpy.and.identity + ++ ' to have been called before first call to spy ' + ++ latterSpy.and.identity + ++ ' (no interleaved calls)'; ++ } else if (latest2ndSpyCall > latest1stSpyCall) { ++ result.message = ++ 'Expected first call to spy ' + ++ latterSpy.and.identity + ++ ' to have been called after latest call to spy ' + ++ firstSpy.and.identity + ++ ' (no interleaved calls)'; ++ } else { ++ result.message = ++ 'Expected spy ' + ++ firstSpy.and.identity + ++ ' to have been called before spy ' + ++ latterSpy.and.identity; ++ } ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toHaveBeenCalledBefore; ++}; ++ ++getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toHaveBeenCalledOnceWith(...arguments)' ++ ); ++ ++ /** ++ * {@link expect} the actual (a {@link Spy}) to have been called exactly once, and exactly with the particular arguments. ++ * @function ++ * @name matchers#toHaveBeenCalledOnceWith ++ * @since 3.6.0 ++ * @param {...Object} - The arguments to look for ++ * @example ++ * expect(mySpy).toHaveBeenCalledOnceWith('foo', 'bar', 2); ++ */ ++ function toHaveBeenCalledOnceWith(util) { ++ return { ++ compare: function() { ++ var args = Array.prototype.slice.call(arguments, 0), ++ actual = args[0], ++ expectedArgs = args.slice(1); ++ ++ if (!j$.isSpy(actual)) { ++ throw new Error( ++ getErrorMsg('Expected a spy, but got ' + util.pp(actual) + '.') ++ ); ++ } ++ ++ var prettyPrintedCalls = actual.calls ++ .allArgs() ++ .map(function(argsForCall) { ++ return ' ' + util.pp(argsForCall); ++ }); ++ ++ if ( ++ actual.calls.count() === 1 && ++ util.contains(actual.calls.allArgs(), expectedArgs) ++ ) { ++ return { ++ pass: true, ++ message: ++ 'Expected spy ' + ++ actual.and.identity + ++ ' to have been called 0 times, multiple times, or once, but with arguments different from:\n' + ++ ' ' + ++ util.pp(expectedArgs) + ++ '\n' + ++ 'But the actual call was:\n' + ++ prettyPrintedCalls.join(',\n') + ++ '.\n\n' ++ }; ++ } ++ ++ function getDiffs() { ++ return actual.calls.allArgs().map(function(argsForCall, callIx) { ++ var diffBuilder = new j$.DiffBuilder(); ++ util.equals(argsForCall, expectedArgs, diffBuilder); ++ return diffBuilder.getMessage(); ++ }); ++ } ++ ++ function butString() { ++ switch (actual.calls.count()) { ++ case 0: ++ return 'But it was never called.\n\n'; ++ case 1: ++ return ( ++ 'But the actual call was:\n' + ++ prettyPrintedCalls.join(',\n') + ++ '.\n' + ++ getDiffs().join('\n') + ++ '\n\n' ++ ); ++ default: ++ return ( ++ 'But the actual calls were:\n' + ++ prettyPrintedCalls.join(',\n') + ++ '.\n\n' ++ ); ++ } ++ } ++ ++ return { ++ pass: false, ++ message: ++ 'Expected spy ' + ++ actual.and.identity + ++ ' to have been called only once, and with given args:\n' + ++ ' ' + ++ util.pp(expectedArgs) + ++ '\n' + ++ butString() ++ }; ++ } ++ }; ++ } ++ ++ return toHaveBeenCalledOnceWith; ++}; ++ ++getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toHaveBeenCalledTimes()' ++ ); ++ ++ /** ++ * {@link expect} the actual (a {@link Spy}) to have been called the specified number of times. ++ * @function ++ * @name matchers#toHaveBeenCalledTimes ++ * @since 2.4.0 ++ * @param {Number} expected - The number of invocations to look for. ++ * @example ++ * expect(mySpy).toHaveBeenCalledTimes(3); ++ */ ++ function toHaveBeenCalledTimes(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ if (!j$.isSpy(actual)) { ++ throw new Error( ++ getErrorMsg( ++ 'Expected a spy, but got ' + matchersUtil.pp(actual) + '.' ++ ) ++ ); ++ } ++ ++ var args = Array.prototype.slice.call(arguments, 0), ++ result = { pass: false }; ++ ++ if (!j$.isNumber_(expected)) { ++ throw new Error( ++ getErrorMsg( ++ 'The expected times failed is a required argument and must be a number.' ++ ) ++ ); ++ } ++ ++ actual = args[0]; ++ var calls = actual.calls.count(); ++ var timesMessage = expected === 1 ? 'once' : expected + ' times'; ++ result.pass = calls === expected; ++ result.message = result.pass ++ ? 'Expected spy ' + ++ actual.and.identity + ++ ' not to have been called ' + ++ timesMessage + ++ '. It was called ' + ++ calls + ++ ' times.' ++ : 'Expected spy ' + ++ actual.and.identity + ++ ' to have been called ' + ++ timesMessage + ++ '. It was called ' + ++ calls + ++ ' times.'; ++ return result; ++ } ++ }; ++ } ++ ++ return toHaveBeenCalledTimes; ++}; ++ ++getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toHaveBeenCalledWith(...arguments)' ++ ); ++ ++ /** ++ * {@link expect} the actual (a {@link Spy}) to have been called with particular arguments at least once. ++ * @function ++ * @name matchers#toHaveBeenCalledWith ++ * @since 1.3.0 ++ * @param {...Object} - The arguments to look for ++ * @example ++ * expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2); ++ */ ++ function toHaveBeenCalledWith(matchersUtil) { ++ return { ++ compare: function() { ++ var args = Array.prototype.slice.call(arguments, 0), ++ actual = args[0], ++ expectedArgs = args.slice(1), ++ result = { pass: false }; ++ ++ if (!j$.isSpy(actual)) { ++ throw new Error( ++ getErrorMsg( ++ 'Expected a spy, but got ' + matchersUtil.pp(actual) + '.' ++ ) ++ ); ++ } ++ ++ if (!actual.calls.any()) { ++ result.message = function() { ++ return ( ++ 'Expected spy ' + ++ actual.and.identity + ++ ' to have been called with:\n' + ++ ' ' + ++ matchersUtil.pp(expectedArgs) + ++ '\nbut it was never called.' ++ ); ++ }; ++ return result; ++ } ++ ++ if (matchersUtil.contains(actual.calls.allArgs(), expectedArgs)) { ++ result.pass = true; ++ result.message = function() { ++ return ( ++ 'Expected spy ' + ++ actual.and.identity + ++ ' not to have been called with:\n' + ++ ' ' + ++ matchersUtil.pp(expectedArgs) + ++ '\nbut it was.' ++ ); ++ }; ++ } else { ++ result.message = function() { ++ var prettyPrintedCalls = actual.calls ++ .allArgs() ++ .map(function(argsForCall) { ++ return ' ' + matchersUtil.pp(argsForCall); ++ }); ++ ++ var diffs = actual.calls ++ .allArgs() ++ .map(function(argsForCall, callIx) { ++ var diffBuilder = new j$.DiffBuilder(); ++ matchersUtil.equals(argsForCall, expectedArgs, diffBuilder); ++ return ( ++ 'Call ' + ++ callIx + ++ ':\n' + ++ diffBuilder.getMessage().replace(/^/gm, ' ') ++ ); ++ }); ++ ++ return ( ++ 'Expected spy ' + ++ actual.and.identity + ++ ' to have been called with:\n' + ++ ' ' + ++ matchersUtil.pp(expectedArgs) + ++ '\n' + ++ '' + ++ 'but actual calls were:\n' + ++ prettyPrintedCalls.join(',\n') + ++ '.\n\n' + ++ diffs.join('\n') ++ ); ++ }; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toHaveBeenCalledWith; ++}; ++ ++getJasmineRequireObj().toHaveClass = function(j$) { ++ /** ++ * {@link expect} the actual value to be a DOM element that has the expected class ++ * @function ++ * @name matchers#toHaveClass ++ * @since 3.0.0 ++ * @param {Object} expected - The class name to test for ++ * @example ++ * var el = document.createElement('div'); ++ * el.className = 'foo bar baz'; ++ * expect(el).toHaveClass('bar'); ++ */ ++ function toHaveClass(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ if (!isElement(actual)) { ++ throw new Error(matchersUtil.pp(actual) + ' is not a DOM element'); ++ } ++ ++ return { ++ pass: actual.classList.contains(expected) ++ }; ++ } ++ }; ++ } ++ ++ function isElement(maybeEl) { ++ return ( ++ maybeEl && maybeEl.classList && j$.isFunction_(maybeEl.classList.contains) ++ ); ++ } ++ ++ return toHaveClass; ++}; ++ ++getJasmineRequireObj().toHaveSize = function(j$) { ++ /** ++ * {@link expect} the actual size to be equal to the expected, using array-like length or object keys size. ++ * @function ++ * @name matchers#toHaveSize ++ * @since 3.6.0 ++ * @param {Object} expected - Expected size ++ * @example ++ * array = [1,2]; ++ * expect(array).toHaveSize(2); ++ */ ++ function toHaveSize() { ++ return { ++ compare: function(actual, expected) { ++ var result = { ++ pass: false ++ }; ++ ++ if ( ++ j$.isA_('WeakSet', actual) || ++ j$.isWeakMap(actual) || ++ j$.isDataView(actual) ++ ) { ++ throw new Error('Cannot get size of ' + actual + '.'); ++ } ++ ++ if (j$.isSet(actual) || j$.isMap(actual)) { ++ result.pass = actual.size === expected; ++ } else if (isLength(actual.length)) { ++ result.pass = actual.length === expected; ++ } else { ++ result.pass = Object.keys(actual).length === expected; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // eslint-disable-line compat/compat ++ function isLength(value) { ++ return ( ++ typeof value == 'number' && ++ value > -1 && ++ value % 1 === 0 && ++ value <= MAX_SAFE_INTEGER ++ ); ++ } ++ ++ return toHaveSize; ++}; ++ ++getJasmineRequireObj().toMatch = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect().toMatch( || )' ++ ); ++ ++ /** ++ * {@link expect} the actual value to match a regular expression ++ * @function ++ * @name matchers#toMatch ++ * @since 1.3.0 ++ * @param {RegExp|String} expected - Value to look for in the string. ++ * @example ++ * expect("my string").toMatch(/string$/); ++ * expect("other string").toMatch("her"); ++ */ ++ function toMatch() { ++ return { ++ compare: function(actual, expected) { ++ if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { ++ throw new Error(getErrorMsg('Expected is not a String or a RegExp')); ++ } ++ ++ var regexp = new RegExp(expected); ++ ++ return { ++ pass: regexp.test(actual) ++ }; ++ } ++ }; ++ } ++ ++ return toMatch; ++}; ++ ++getJasmineRequireObj().toThrow = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect(function() {}).toThrow()' ++ ); ++ ++ /** ++ * {@link expect} a function to `throw` something. ++ * @function ++ * @name matchers#toThrow ++ * @since 2.0.0 ++ * @param {Object} [expected] - Value that should be thrown. If not provided, simply the fact that something was thrown will be checked. ++ * @example ++ * expect(function() { return 'things'; }).toThrow('foo'); ++ * expect(function() { return 'stuff'; }).toThrow(); ++ */ ++ function toThrow(matchersUtil) { ++ return { ++ compare: function(actual, expected) { ++ var result = { pass: false }, ++ threw = false, ++ thrown; ++ ++ if (typeof actual != 'function') { ++ throw new Error(getErrorMsg('Actual is not a Function')); ++ } ++ ++ try { ++ actual(); ++ } catch (e) { ++ threw = true; ++ thrown = e; ++ } ++ ++ if (!threw) { ++ result.message = 'Expected function to throw an exception.'; ++ return result; ++ } ++ ++ if (arguments.length == 1) { ++ result.pass = true; ++ result.message = function() { ++ return ( ++ 'Expected function not to throw, but it threw ' + ++ matchersUtil.pp(thrown) + ++ '.' ++ ); ++ }; ++ ++ return result; ++ } ++ ++ if (matchersUtil.equals(thrown, expected)) { ++ result.pass = true; ++ result.message = function() { ++ return ( ++ 'Expected function not to throw ' + ++ matchersUtil.pp(expected) + ++ '.' ++ ); ++ }; ++ } else { ++ result.message = function() { ++ return ( ++ 'Expected function to throw ' + ++ matchersUtil.pp(expected) + ++ ', but it threw ' + ++ matchersUtil.pp(thrown) + ++ '.' ++ ); ++ }; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ ++ return toThrow; ++}; ++ ++getJasmineRequireObj().toThrowError = function(j$) { ++ var getErrorMsg = j$.formatErrorMsg( ++ '', ++ 'expect(function() {}).toThrowError(, )' ++ ); ++ ++ /** ++ * {@link expect} a function to `throw` an `Error`. ++ * @function ++ * @name matchers#toThrowError ++ * @since 2.0.0 ++ * @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used. ++ * @param {RegExp|String} [message] - The message that should be set on the thrown `Error` ++ * @example ++ * expect(function() { return 'things'; }).toThrowError(MyCustomError, 'message'); ++ * expect(function() { return 'things'; }).toThrowError(MyCustomError, /bar/); ++ * expect(function() { return 'stuff'; }).toThrowError(MyCustomError); ++ * expect(function() { return 'other'; }).toThrowError(/foo/); ++ * expect(function() { return 'other'; }).toThrowError(); ++ */ ++ function toThrowError(matchersUtil) { ++ return { ++ compare: function(actual) { ++ var errorMatcher = getMatcher.apply(null, arguments), ++ thrown; ++ ++ if (typeof actual != 'function') { ++ throw new Error(getErrorMsg('Actual is not a Function')); ++ } ++ ++ try { ++ actual(); ++ return fail('Expected function to throw an Error.'); ++ } catch (e) { ++ thrown = e; ++ } ++ ++ if (!j$.isError_(thrown)) { ++ return fail(function() { ++ return ( ++ 'Expected function to throw an Error, but it threw ' + ++ matchersUtil.pp(thrown) + ++ '.' ++ ); ++ }); ++ } ++ ++ return errorMatcher.match(thrown); ++ } ++ }; ++ ++ function getMatcher() { ++ var expected, errorType; ++ ++ if (arguments[2]) { ++ errorType = arguments[1]; ++ expected = arguments[2]; ++ if (!isAnErrorType(errorType)) { ++ throw new Error(getErrorMsg('Expected error type is not an Error.')); ++ } ++ ++ return exactMatcher(expected, errorType); ++ } else if (arguments[1]) { ++ expected = arguments[1]; ++ ++ if (isAnErrorType(arguments[1])) { ++ return exactMatcher(null, arguments[1]); ++ } else { ++ return exactMatcher(arguments[1], null); ++ } ++ } else { ++ return anyMatcher(); ++ } ++ } ++ ++ function anyMatcher() { ++ return { ++ match: function(error) { ++ return pass( ++ 'Expected function not to throw an Error, but it threw ' + ++ j$.fnNameFor(error) + ++ '.' ++ ); ++ } ++ }; ++ } ++ ++ function exactMatcher(expected, errorType) { ++ if (expected && !isStringOrRegExp(expected)) { ++ if (errorType) { ++ throw new Error( ++ getErrorMsg('Expected error message is not a string or RegExp.') ++ ); ++ } else { ++ throw new Error( ++ getErrorMsg('Expected is not an Error, string, or RegExp.') ++ ); ++ } ++ } ++ ++ function messageMatch(message) { ++ if (typeof expected == 'string') { ++ return expected == message; ++ } else { ++ return expected.test(message); ++ } ++ } ++ ++ var errorTypeDescription = errorType ++ ? j$.fnNameFor(errorType) ++ : 'an exception'; ++ ++ function thrownDescription(thrown) { ++ var thrownName = errorType ++ ? j$.fnNameFor(thrown.constructor) ++ : 'an exception', ++ thrownMessage = ''; ++ ++ if (expected) { ++ thrownMessage = ' with message ' + matchersUtil.pp(thrown.message); ++ } ++ ++ return thrownName + thrownMessage; ++ } ++ ++ function messageDescription() { ++ if (expected === null) { ++ return ''; ++ } else if (expected instanceof RegExp) { ++ return ' with a message matching ' + matchersUtil.pp(expected); ++ } else { ++ return ' with message ' + matchersUtil.pp(expected); ++ } ++ } ++ ++ function matches(error) { ++ return ( ++ (errorType === null || error instanceof errorType) && ++ (expected === null || messageMatch(error.message)) ++ ); ++ } ++ ++ return { ++ match: function(thrown) { ++ if (matches(thrown)) { ++ return pass(function() { ++ return ( ++ 'Expected function not to throw ' + ++ errorTypeDescription + ++ messageDescription() + ++ '.' ++ ); ++ }); ++ } else { ++ return fail(function() { ++ return ( ++ 'Expected function to throw ' + ++ errorTypeDescription + ++ messageDescription() + ++ ', but it threw ' + ++ thrownDescription(thrown) + ++ '.' ++ ); ++ }); ++ } ++ } ++ }; ++ } ++ ++ function isStringOrRegExp(potential) { ++ return potential instanceof RegExp || typeof potential == 'string'; ++ } ++ ++ function isAnErrorType(type) { ++ if (typeof type !== 'function') { ++ return false; ++ } ++ ++ var Surrogate = function() {}; ++ Surrogate.prototype = type.prototype; ++ return j$.isError_(new Surrogate()); ++ } ++ } ++ ++ function pass(message) { ++ return { ++ pass: true, ++ message: message ++ }; ++ } ++ ++ function fail(message) { ++ return { ++ pass: false, ++ message: message ++ }; ++ } ++ ++ return toThrowError; ++}; ++ ++getJasmineRequireObj().toThrowMatching = function(j$) { ++ var usageError = j$.formatErrorMsg( ++ '', ++ 'expect(function() {}).toThrowMatching()' ++ ); ++ ++ /** ++ * {@link expect} a function to `throw` something matching a predicate. ++ * @function ++ * @name matchers#toThrowMatching ++ * @since 3.0.0 ++ * @param {Function} predicate - A function that takes the thrown exception as its parameter and returns true if it matches. ++ * @example ++ * expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; }); ++ */ ++ function toThrowMatching(matchersUtil) { ++ return { ++ compare: function(actual, predicate) { ++ var thrown; ++ ++ if (typeof actual !== 'function') { ++ throw new Error(usageError('Actual is not a Function')); ++ } ++ ++ if (typeof predicate !== 'function') { ++ throw new Error(usageError('Predicate is not a Function')); ++ } ++ ++ try { ++ actual(); ++ return fail('Expected function to throw an exception.'); ++ } catch (e) { ++ thrown = e; ++ } ++ ++ if (predicate(thrown)) { ++ return pass( ++ 'Expected function not to throw an exception matching a predicate.' ++ ); ++ } else { ++ return fail(function() { ++ return ( ++ 'Expected function to throw an exception matching a predicate, ' + ++ 'but it threw ' + ++ thrownDescription(thrown) + ++ '.' ++ ); ++ }); ++ } ++ } ++ }; ++ ++ function thrownDescription(thrown) { ++ if (thrown && thrown.constructor) { ++ return ( ++ j$.fnNameFor(thrown.constructor) + ++ ' with message ' + ++ matchersUtil.pp(thrown.message) ++ ); ++ } else { ++ return matchersUtil.pp(thrown); ++ } ++ } ++ } ++ ++ function pass(message) { ++ return { ++ pass: true, ++ message: message ++ }; ++ } ++ ++ function fail(message) { ++ return { ++ pass: false, ++ message: message ++ }; ++ } ++ ++ return toThrowMatching; ++}; ++ ++getJasmineRequireObj().MockDate = function() { ++ function MockDate(global) { ++ var self = this; ++ var currentTime = 0; ++ ++ if (!global || !global.Date) { ++ self.install = function() {}; ++ self.tick = function() {}; ++ self.uninstall = function() {}; ++ return self; ++ } ++ ++ var GlobalDate = global.Date; ++ ++ self.install = function(mockDate) { ++ if (mockDate instanceof GlobalDate) { ++ currentTime = mockDate.getTime(); ++ } else { ++ currentTime = new GlobalDate().getTime(); ++ } ++ ++ global.Date = FakeDate; ++ }; ++ ++ self.tick = function(millis) { ++ millis = millis || 0; ++ currentTime = currentTime + millis; ++ }; ++ ++ self.uninstall = function() { ++ currentTime = 0; ++ global.Date = GlobalDate; ++ }; ++ ++ createDateProperties(); ++ ++ return self; ++ ++ function FakeDate() { ++ switch (arguments.length) { ++ case 0: ++ return new GlobalDate(currentTime); ++ case 1: ++ return new GlobalDate(arguments[0]); ++ case 2: ++ return new GlobalDate(arguments[0], arguments[1]); ++ case 3: ++ return new GlobalDate(arguments[0], arguments[1], arguments[2]); ++ case 4: ++ return new GlobalDate( ++ arguments[0], ++ arguments[1], ++ arguments[2], ++ arguments[3] ++ ); ++ case 5: ++ return new GlobalDate( ++ arguments[0], ++ arguments[1], ++ arguments[2], ++ arguments[3], ++ arguments[4] ++ ); ++ case 6: ++ return new GlobalDate( ++ arguments[0], ++ arguments[1], ++ arguments[2], ++ arguments[3], ++ arguments[4], ++ arguments[5] ++ ); ++ default: ++ return new GlobalDate( ++ arguments[0], ++ arguments[1], ++ arguments[2], ++ arguments[3], ++ arguments[4], ++ arguments[5], ++ arguments[6] ++ ); ++ } ++ } ++ ++ function createDateProperties() { ++ FakeDate.prototype = GlobalDate.prototype; ++ ++ FakeDate.now = function() { ++ if (GlobalDate.now) { ++ return currentTime; ++ } else { ++ throw new Error('Browser does not support Date.now()'); ++ } ++ }; ++ ++ FakeDate.toSource = GlobalDate.toSource; ++ FakeDate.toString = GlobalDate.toString; ++ FakeDate.parse = GlobalDate.parse; ++ FakeDate.UTC = GlobalDate.UTC; ++ } ++ } ++ ++ return MockDate; ++}; ++ ++getJasmineRequireObj().makePrettyPrinter = function(j$) { ++ function SinglePrettyPrintRun(customObjectFormatters, pp) { ++ this.customObjectFormatters_ = customObjectFormatters; ++ this.ppNestLevel_ = 0; ++ this.seen = []; ++ this.length = 0; ++ this.stringParts = []; ++ this.pp_ = pp; ++ } ++ ++ function hasCustomToString(value) { ++ // value.toString !== Object.prototype.toString if value has no custom toString but is from another context (e.g. ++ // iframe, web worker) ++ try { ++ return ( ++ j$.isFunction_(value.toString) && ++ value.toString !== Object.prototype.toString && ++ value.toString() !== Object.prototype.toString.call(value) ++ ); ++ } catch (e) { ++ // The custom toString() threw. ++ return true; ++ } ++ } ++ ++ SinglePrettyPrintRun.prototype.format = function(value) { ++ this.ppNestLevel_++; ++ try { ++ var customFormatResult = this.applyCustomFormatters_(value); ++ ++ if (customFormatResult) { ++ this.emitScalar(customFormatResult); ++ } else if (j$.util.isUndefined(value)) { ++ this.emitScalar('undefined'); ++ } else if (value === null) { ++ this.emitScalar('null'); ++ } else if (value === 0 && 1 / value === -Infinity) { ++ this.emitScalar('-0'); ++ } else if (value === j$.getGlobal()) { ++ this.emitScalar(''); ++ } else if (value.jasmineToString) { ++ this.emitScalar(value.jasmineToString(this.pp_)); ++ } else if (typeof value === 'string') { ++ this.emitString(value); ++ } else if (j$.isSpy(value)) { ++ this.emitScalar('spy on ' + value.and.identity); ++ } else if (j$.isSpy(value.toString)) { ++ this.emitScalar('spy on ' + value.toString.and.identity); ++ } else if (value instanceof RegExp) { ++ this.emitScalar(value.toString()); ++ } else if (typeof value === 'function') { ++ this.emitScalar('Function'); ++ } else if (j$.isDomNode(value)) { ++ if (value.tagName) { ++ this.emitDomElement(value); ++ } else { ++ this.emitScalar('HTMLNode'); ++ } ++ } else if (value instanceof Date) { ++ this.emitScalar('Date(' + value + ')'); ++ } else if (j$.isSet(value)) { ++ this.emitSet(value); ++ } else if (j$.isMap(value)) { ++ this.emitMap(value); ++ } else if (j$.isTypedArray_(value)) { ++ this.emitTypedArray(value); ++ } else if ( ++ value.toString && ++ typeof value === 'object' && ++ !j$.isArray_(value) && ++ hasCustomToString(value) ++ ) { ++ try { ++ this.emitScalar(value.toString()); ++ } catch (e) { ++ this.emitScalar('has-invalid-toString-method'); ++ } ++ } else if (j$.util.arrayContains(this.seen, value)) { ++ this.emitScalar( ++ '' ++ ); ++ } else if (j$.isArray_(value) || j$.isA_('Object', value)) { ++ this.seen.push(value); ++ if (j$.isArray_(value)) { ++ this.emitArray(value); ++ } else { ++ this.emitObject(value); ++ } ++ this.seen.pop(); ++ } else { ++ this.emitScalar(value.toString()); ++ } ++ } catch (e) { ++ if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) { ++ throw e; ++ } ++ } finally { ++ this.ppNestLevel_--; ++ } ++ }; ++ ++ SinglePrettyPrintRun.prototype.applyCustomFormatters_ = function(value) { ++ return customFormat(value, this.customObjectFormatters_); ++ }; ++ ++ SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) { ++ var objKeys = keys(obj, j$.isArray_(obj)); ++ var isGetter = function isGetter(prop) {}; ++ ++ if (obj.__lookupGetter__) { ++ isGetter = function isGetter(prop) { ++ var getter = obj.__lookupGetter__(prop); ++ return !j$.util.isUndefined(getter) && getter !== null; ++ }; ++ } ++ var length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); ++ for (var i = 0; i < length; i++) { ++ var property = objKeys[i]; ++ fn(property, isGetter(property)); ++ } ++ ++ return objKeys.length > length; ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitScalar = function(value) { ++ this.append(value); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitString = function(value) { ++ this.append("'" + value + "'"); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitArray = function(array) { ++ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { ++ this.append('Array'); ++ return; ++ } ++ var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); ++ this.append('[ '); ++ for (var i = 0; i < length; i++) { ++ if (i > 0) { ++ this.append(', '); ++ } ++ this.format(array[i]); ++ } ++ if (array.length > length) { ++ this.append(', ...'); ++ } ++ ++ var self = this; ++ var first = array.length === 0; ++ var truncated = this.iterateObject(array, function(property, isGetter) { ++ if (first) { ++ first = false; ++ } else { ++ self.append(', '); ++ } ++ ++ self.formatProperty(array, property, isGetter); ++ }); ++ ++ if (truncated) { ++ this.append(', ...'); ++ } ++ ++ this.append(' ]'); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitSet = function(set) { ++ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { ++ this.append('Set'); ++ return; ++ } ++ this.append('Set( '); ++ var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); ++ var i = 0; ++ set.forEach(function(value, key) { ++ if (i >= size) { ++ return; ++ } ++ if (i > 0) { ++ this.append(', '); ++ } ++ this.format(value); ++ ++ i++; ++ }, this); ++ if (set.size > size) { ++ this.append(', ...'); ++ } ++ this.append(' )'); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitMap = function(map) { ++ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { ++ this.append('Map'); ++ return; ++ } ++ this.append('Map( '); ++ var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); ++ var i = 0; ++ map.forEach(function(value, key) { ++ if (i >= size) { ++ return; ++ } ++ if (i > 0) { ++ this.append(', '); ++ } ++ this.format([key, value]); ++ ++ i++; ++ }, this); ++ if (map.size > size) { ++ this.append(', ...'); ++ } ++ this.append(' )'); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitObject = function(obj) { ++ var ctor = obj.constructor, ++ constructorName; ++ ++ constructorName = ++ typeof ctor === 'function' && obj instanceof ctor ++ ? j$.fnNameFor(obj.constructor) ++ : 'null'; ++ ++ this.append(constructorName); ++ ++ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { ++ return; ++ } ++ ++ var self = this; ++ this.append('({ '); ++ var first = true; ++ ++ var truncated = this.iterateObject(obj, function(property, isGetter) { ++ if (first) { ++ first = false; ++ } else { ++ self.append(', '); ++ } ++ ++ self.formatProperty(obj, property, isGetter); ++ }); ++ ++ if (truncated) { ++ this.append(', ...'); ++ } ++ ++ this.append(' })'); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitTypedArray = function(arr) { ++ var constructorName = j$.fnNameFor(arr.constructor), ++ limitedArray = Array.prototype.slice.call( ++ arr, ++ 0, ++ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH ++ ), ++ itemsString = Array.prototype.join.call(limitedArray, ', '); ++ ++ if (limitedArray.length !== arr.length) { ++ itemsString += ', ...'; ++ } ++ ++ this.append(constructorName + ' [ ' + itemsString + ' ]'); ++ }; ++ ++ SinglePrettyPrintRun.prototype.emitDomElement = function(el) { ++ var tagName = el.tagName.toLowerCase(), ++ attrs = el.attributes, ++ i, ++ len = attrs.length, ++ out = '<' + tagName, ++ attr; ++ ++ for (i = 0; i < len; i++) { ++ attr = attrs[i]; ++ out += ' ' + attr.name; ++ ++ if (attr.value !== '') { ++ out += '="' + attr.value + '"'; ++ } ++ } ++ ++ out += '>'; ++ ++ if (el.childElementCount !== 0 || el.textContent !== '') { ++ out += '...'; ++ } ++ ++ this.append(out); ++ }; ++ ++ SinglePrettyPrintRun.prototype.formatProperty = function( ++ obj, ++ property, ++ isGetter ++ ) { ++ this.append(property); ++ this.append(': '); ++ if (isGetter) { ++ this.append(''); ++ } else { ++ this.format(obj[property]); ++ } ++ }; ++ ++ SinglePrettyPrintRun.prototype.append = function(value) { ++ // This check protects us from the rare case where an object has overriden ++ // `toString()` with an invalid implementation (returning a non-string). ++ if (typeof value !== 'string') { ++ value = Object.prototype.toString.call(value); ++ } ++ ++ var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length); ++ this.length += result.value.length; ++ this.stringParts.push(result.value); ++ ++ if (result.truncated) { ++ throw new MaxCharsReachedError(); ++ } ++ }; ++ ++ function truncate(s, maxlen) { ++ if (s.length <= maxlen) { ++ return { value: s, truncated: false }; ++ } ++ ++ s = s.substring(0, maxlen - 4) + ' ...'; ++ return { value: s, truncated: true }; ++ } ++ ++ function MaxCharsReachedError() { ++ this.message = ++ 'Exceeded ' + ++ j$.MAX_PRETTY_PRINT_CHARS + ++ ' characters while pretty-printing a value'; ++ } ++ ++ MaxCharsReachedError.prototype = new Error(); ++ ++ function keys(obj, isArray) { ++ var allKeys = Object.keys ++ ? Object.keys(obj) ++ : (function(o) { ++ var keys = []; ++ for (var key in o) { ++ if (j$.util.has(o, key)) { ++ keys.push(key); ++ } ++ } ++ return keys; ++ })(obj); ++ ++ if (!isArray) { ++ return allKeys; ++ } ++ ++ if (allKeys.length === 0) { ++ return allKeys; ++ } ++ ++ var extraKeys = []; ++ for (var i = 0; i < allKeys.length; i++) { ++ if (!/^[0-9]+$/.test(allKeys[i])) { ++ extraKeys.push(allKeys[i]); ++ } ++ } ++ ++ return extraKeys; ++ } ++ ++ function customFormat(value, customObjectFormatters) { ++ var i, result; ++ ++ for (i = 0; i < customObjectFormatters.length; i++) { ++ result = customObjectFormatters[i](value); ++ ++ if (result !== undefined) { ++ return result; ++ } ++ } ++ } ++ ++ return function(customObjectFormatters) { ++ customObjectFormatters = customObjectFormatters || []; ++ ++ var pp = function(value) { ++ var prettyPrinter = new SinglePrettyPrintRun(customObjectFormatters, pp); ++ prettyPrinter.format(value); ++ return prettyPrinter.stringParts.join(''); ++ }; ++ ++ pp.customFormat_ = function(value) { ++ return customFormat(value, customObjectFormatters); ++ }; ++ ++ return pp; ++ }; ++}; ++ ++getJasmineRequireObj().QueueRunner = function(j$) { ++ var nextid = 1; ++ ++ function StopExecutionError() {} ++ StopExecutionError.prototype = new Error(); ++ j$.StopExecutionError = StopExecutionError; ++ ++ function once(fn) { ++ var called = false; ++ return function(arg) { ++ if (!called) { ++ called = true; ++ // Direct call using single parameter, because cleanup/next does not need more ++ fn(arg); ++ } ++ return null; ++ }; ++ } ++ ++ function emptyFn() {} ++ ++ function QueueRunner(attrs) { ++ this.id_ = nextid++; ++ var queueableFns = attrs.queueableFns || []; ++ this.queueableFns = queueableFns.concat(attrs.cleanupFns || []); ++ this.firstCleanupIx = queueableFns.length; ++ this.onComplete = attrs.onComplete || emptyFn; ++ this.clearStack = ++ attrs.clearStack || ++ function(fn) { ++ fn(); ++ }; ++ this.onException = attrs.onException || emptyFn; ++ this.userContext = attrs.userContext || new j$.UserContext(); ++ this.timeout = attrs.timeout || { ++ setTimeout: setTimeout, ++ clearTimeout: clearTimeout ++ }; ++ this.fail = attrs.fail || emptyFn; ++ this.globalErrors = attrs.globalErrors || { ++ pushListener: emptyFn, ++ popListener: emptyFn ++ }; ++ this.completeOnFirstError = !!attrs.completeOnFirstError; ++ this.errored = false; ++ ++ if (typeof this.onComplete !== 'function') { ++ throw new Error('invalid onComplete ' + JSON.stringify(this.onComplete)); ++ } ++ this.deprecated = attrs.deprecated; ++ } ++ ++ QueueRunner.prototype.execute = function() { ++ var self = this; ++ this.handleFinalError = function(message, source, lineno, colno, error) { ++ // Older browsers would send the error as the first parameter. HTML5 ++ // specifies the the five parameters above. The error instance should ++ // be preffered, otherwise the call stack would get lost. ++ self.onException(error || message); ++ }; ++ this.globalErrors.pushListener(this.handleFinalError); ++ this.run(0); ++ }; ++ ++ QueueRunner.prototype.skipToCleanup = function(lastRanIndex) { ++ if (lastRanIndex < this.firstCleanupIx) { ++ this.run(this.firstCleanupIx); ++ } else { ++ this.run(lastRanIndex + 1); ++ } ++ }; ++ ++ QueueRunner.prototype.clearTimeout = function(timeoutId) { ++ Function.prototype.apply.apply(this.timeout.clearTimeout, [ ++ j$.getGlobal(), ++ [timeoutId] ++ ]); ++ }; ++ ++ QueueRunner.prototype.setTimeout = function(fn, timeout) { ++ return Function.prototype.apply.apply(this.timeout.setTimeout, [ ++ j$.getGlobal(), ++ [fn, timeout] ++ ]); ++ }; ++ ++ QueueRunner.prototype.attempt = function attempt(iterativeIndex) { ++ var self = this, ++ completedSynchronously = true, ++ handleError = function handleError(error) { ++ onException(error); ++ }, ++ cleanup = once(function cleanup() { ++ if (timeoutId !== void 0) { ++ self.clearTimeout(timeoutId); ++ } ++ self.globalErrors.popListener(handleError); ++ }), ++ next = once(function next(err) { ++ cleanup(); ++ ++ if (j$.isError_(err)) { ++ if (!(err instanceof StopExecutionError) && !err.jasmineMessage) { ++ self.fail(err); ++ } ++ self.errored = errored = true; ++ } ++ ++ function runNext() { ++ if (self.completeOnFirstError && errored) { ++ self.skipToCleanup(iterativeIndex); ++ } else { ++ self.run(iterativeIndex + 1); ++ } ++ } ++ ++ if (completedSynchronously) { ++ self.setTimeout(runNext); ++ } else { ++ runNext(); ++ } ++ }), ++ errored = false, ++ queueableFn = self.queueableFns[iterativeIndex], ++ timeoutId, ++ maybeThenable; ++ ++ next.fail = function nextFail() { ++ self.fail.apply(null, arguments); ++ self.errored = errored = true; ++ next(); ++ }; ++ ++ self.globalErrors.pushListener(handleError); ++ ++ if (queueableFn.timeout !== undefined) { ++ var timeoutInterval = queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL; ++ timeoutId = self.setTimeout(function() { ++ var error = new Error( ++ 'Timeout - Async function did not complete within ' + ++ timeoutInterval + ++ 'ms ' + ++ (queueableFn.timeout ++ ? '(custom timeout)' ++ : '(set by jasmine.DEFAULT_TIMEOUT_INTERVAL)') ++ ); ++ onException(error); ++ next(); ++ }, timeoutInterval); ++ } ++ ++ try { ++ if (queueableFn.fn.length === 0) { ++ maybeThenable = queueableFn.fn.call(self.userContext); ++ ++ if (maybeThenable && j$.isFunction_(maybeThenable.then)) { ++ maybeThenable.then(next, onPromiseRejection); ++ completedSynchronously = false; ++ return { completedSynchronously: false }; ++ } ++ } else { ++ maybeThenable = queueableFn.fn.call(self.userContext, next); ++ this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable); ++ completedSynchronously = false; ++ return { completedSynchronously: false }; ++ } ++ } catch (e) { ++ onException(e); ++ self.errored = errored = true; ++ } ++ ++ cleanup(); ++ return { completedSynchronously: true, errored: errored }; ++ ++ function onException(e) { ++ self.onException(e); ++ self.errored = errored = true; ++ } ++ ++ function onPromiseRejection(e) { ++ onException(e); ++ next(); ++ } ++ }; ++ ++ QueueRunner.prototype.run = function(recursiveIndex) { ++ var length = this.queueableFns.length, ++ self = this, ++ iterativeIndex; ++ ++ for ( ++ iterativeIndex = recursiveIndex; ++ iterativeIndex < length; ++ iterativeIndex++ ++ ) { ++ var result = this.attempt(iterativeIndex); ++ ++ if (!result.completedSynchronously) { ++ return; ++ } ++ ++ self.errored = self.errored || result.errored; ++ ++ if (this.completeOnFirstError && result.errored) { ++ this.skipToCleanup(iterativeIndex); ++ return; ++ } ++ } ++ ++ this.clearStack(function() { ++ self.globalErrors.popListener(self.handleFinalError); ++ self.onComplete(self.errored && new StopExecutionError()); ++ }); ++ }; ++ ++ QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) { ++ if (retval && j$.isFunction_(retval.then)) { ++ // Issue a warning that matches the user's code ++ if (j$.isAsyncFunction_(fn)) { ++ this.deprecated( ++ 'An asynchronous before/it/after ' + ++ 'function was defined with the async keyword but also took a ' + ++ 'done callback. This is not supported and will stop working in' + ++ ' the future. Either remove the done callback (recommended) or ' + ++ 'remove the async keyword.' ++ ); ++ } else { ++ this.deprecated( ++ 'An asynchronous before/it/after ' + ++ 'function took a done callback but also returned a promise. ' + ++ 'This is not supported and will stop working in the future. ' + ++ 'Either remove the done callback (recommended) or change the ' + ++ 'function to not return a promise.' ++ ); ++ } ++ } ++ }; ++ ++ return QueueRunner; ++}; ++ ++getJasmineRequireObj().ReportDispatcher = function(j$) { ++ function ReportDispatcher(methods, queueRunnerFactory) { ++ var dispatchedMethods = methods || []; ++ ++ for (var i = 0; i < dispatchedMethods.length; i++) { ++ var method = dispatchedMethods[i]; ++ this[method] = (function(m) { ++ return function() { ++ dispatch(m, arguments); ++ }; ++ })(method); ++ } ++ ++ var reporters = []; ++ var fallbackReporter = null; ++ ++ this.addReporter = function(reporter) { ++ reporters.push(reporter); ++ }; ++ ++ this.provideFallbackReporter = function(reporter) { ++ fallbackReporter = reporter; ++ }; ++ ++ this.clearReporters = function() { ++ reporters = []; ++ }; ++ ++ return this; ++ ++ function dispatch(method, args) { ++ if (reporters.length === 0 && fallbackReporter !== null) { ++ reporters.push(fallbackReporter); ++ } ++ var onComplete = args[args.length - 1]; ++ args = j$.util.argsToArray(args).splice(0, args.length - 1); ++ var fns = []; ++ for (var i = 0; i < reporters.length; i++) { ++ var reporter = reporters[i]; ++ addFn(fns, reporter, method, args); ++ } ++ ++ queueRunnerFactory({ ++ queueableFns: fns, ++ onComplete: onComplete, ++ isReporter: true ++ }); ++ } ++ ++ function addFn(fns, reporter, method, args) { ++ var fn = reporter[method]; ++ if (!fn) { ++ return; ++ } ++ ++ var thisArgs = j$.util.cloneArgs(args); ++ if (fn.length <= 1) { ++ fns.push({ ++ fn: function() { ++ return fn.apply(reporter, thisArgs); ++ } ++ }); ++ } else { ++ fns.push({ ++ fn: function(done) { ++ return fn.apply(reporter, thisArgs.concat([done])); ++ } ++ }); ++ } ++ } ++ } ++ ++ return ReportDispatcher; ++}; ++ ++getJasmineRequireObj().interface = function(jasmine, env) { ++ var jasmineInterface = { ++ /** ++ * Callback passed to parts of the Jasmine base interface. ++ * ++ * By default Jasmine assumes this function completes synchronously. ++ * If you have code that you need to test asynchronously, you can declare that you receive a `done` callback, return a Promise, or use the `async` keyword if it is supported in your environment. ++ * @callback implementationCallback ++ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on. ++ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion. ++ */ ++ ++ /** ++ * Create a group of specs (often called a suite). ++ * ++ * Calls to `describe` can be nested within other calls to compose your suite as a tree. ++ * @name describe ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of the group ++ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs ++ */ ++ describe: function(description, specDefinitions) { ++ return env.describe(description, specDefinitions); ++ }, ++ ++ /** ++ * A temporarily disabled [`describe`]{@link describe} ++ * ++ * Specs within an `xdescribe` will be marked pending and not executed ++ * @name xdescribe ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of the group ++ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs ++ */ ++ xdescribe: function(description, specDefinitions) { ++ return env.xdescribe(description, specDefinitions); ++ }, ++ ++ /** ++ * A focused [`describe`]{@link describe} ++ * ++ * If suites or specs are focused, only those that are focused will be executed ++ * @see fit ++ * @name fdescribe ++ * @since 2.1.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of the group ++ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs ++ */ ++ fdescribe: function(description, specDefinitions) { ++ return env.fdescribe(description, specDefinitions); ++ }, ++ ++ /** ++ * Define a single spec. A spec should contain one or more {@link expect|expectations} that test the state of the code. ++ * ++ * A spec whose expectations all succeed will be passing and a spec with any failures will fail. ++ * The name `it` is a pronoun for the test target, not an abbreviation of anything. It makes the ++ * spec more readable by connecting the function name `it` and the argument `description` as a ++ * complete sentence. ++ * @name it ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of what this spec is checking ++ * @param {implementationCallback} [testFunction] Function that contains the code of your test. If not provided the test will be `pending`. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec. ++ * @see async ++ */ ++ it: function() { ++ return env.it.apply(env, arguments); ++ }, ++ ++ /** ++ * A temporarily disabled [`it`]{@link it} ++ * ++ * The spec will report as `pending` and will not be executed. ++ * @name xit ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of what this spec is checking. ++ * @param {implementationCallback} [testFunction] Function that contains the code of your test. Will not be executed. ++ */ ++ xit: function() { ++ return env.xit.apply(env, arguments); ++ }, ++ ++ /** ++ * A focused [`it`]{@link it} ++ * ++ * If suites or specs are focused, only those that are focused will be executed. ++ * @name fit ++ * @since 2.1.0 ++ * @function ++ * @global ++ * @param {String} description Textual description of what this spec is checking. ++ * @param {implementationCallback} testFunction Function that contains the code of your test. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec. ++ * @see async ++ */ ++ fit: function() { ++ return env.fit.apply(env, arguments); ++ }, ++ ++ /** ++ * Run some shared setup before each of the specs in the {@link describe} in which it is called. ++ * @name beforeEach ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {implementationCallback} [function] Function that contains the code to setup your specs. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeEach. ++ * @see async ++ */ ++ beforeEach: function() { ++ return env.beforeEach.apply(env, arguments); ++ }, ++ ++ /** ++ * Run some shared teardown after each of the specs in the {@link describe} in which it is called. ++ * @name afterEach ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {implementationCallback} [function] Function that contains the code to teardown your specs. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterEach. ++ * @see async ++ */ ++ afterEach: function() { ++ return env.afterEach.apply(env, arguments); ++ }, ++ ++ /** ++ * Run some shared setup once before all of the specs in the {@link describe} are run. ++ * ++ * _Note:_ Be careful, sharing the setup from a beforeAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail. ++ * @name beforeAll ++ * @since 2.1.0 ++ * @function ++ * @global ++ * @param {implementationCallback} [function] Function that contains the code to setup your specs. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeAll. ++ * @see async ++ */ ++ beforeAll: function() { ++ return env.beforeAll.apply(env, arguments); ++ }, ++ ++ /** ++ * Run some shared teardown once after all of the specs in the {@link describe} are run. ++ * ++ * _Note:_ Be careful, sharing the teardown from a afterAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail. ++ * @name afterAll ++ * @since 2.1.0 ++ * @function ++ * @global ++ * @param {implementationCallback} [function] Function that contains the code to teardown your specs. ++ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterAll. ++ * @see async ++ */ ++ afterAll: function() { ++ return env.afterAll.apply(env, arguments); ++ }, ++ ++ /** ++ * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult} ++ * @name setSpecProperty ++ * @since 3.6.0 ++ * @function ++ * @param {String} key The name of the property ++ * @param {*} value The value of the property ++ */ ++ setSpecProperty: function(key, value) { ++ return env.setSpecProperty(key, value); ++ }, ++ ++ /** ++ * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult} ++ * @name setSuiteProperty ++ * @since 3.6.0 ++ * @function ++ * @param {String} key The name of the property ++ * @param {*} value The value of the property ++ */ ++ setSuiteProperty: function(key, value) { ++ return env.setSuiteProperty(key, value); ++ }, ++ ++ /** ++ * Create an expectation for a spec. ++ * @name expect ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {Object} actual - Actual computed value to test expectations against. ++ * @return {matchers} ++ */ ++ expect: function(actual) { ++ return env.expect(actual); ++ }, ++ ++ /** ++ * Create an asynchronous expectation for a spec. Note that the matchers ++ * that are provided by an asynchronous expectation all return promises ++ * which must be either returned from the spec or waited for using `await` ++ * in order for Jasmine to associate them with the correct spec. ++ * @name expectAsync ++ * @since 3.3.0 ++ * @function ++ * @global ++ * @param {Object} actual - Actual computed value to test expectations against. ++ * @return {async-matchers} ++ * @example ++ * await expectAsync(somePromise).toBeResolved(); ++ * @example ++ * return expectAsync(somePromise).toBeResolved(); ++ */ ++ expectAsync: function(actual) { ++ return env.expectAsync(actual); ++ }, ++ ++ /** ++ * Mark a spec as pending, expectation results will be ignored. ++ * @name pending ++ * @since 2.0.0 ++ * @function ++ * @global ++ * @param {String} [message] - Reason the spec is pending. ++ */ ++ pending: function() { ++ return env.pending.apply(env, arguments); ++ }, ++ ++ /** ++ * Explicitly mark a spec as failed. ++ * @name fail ++ * @since 2.1.0 ++ * @function ++ * @global ++ * @param {String|Error} [error] - Reason for the failure. ++ */ ++ fail: function() { ++ return env.fail.apply(env, arguments); ++ }, ++ ++ /** ++ * Install a spy onto an existing object. ++ * @name spyOn ++ * @since 1.3.0 ++ * @function ++ * @global ++ * @param {Object} obj - The object upon which to install the {@link Spy}. ++ * @param {String} methodName - The name of the method to replace with a {@link Spy}. ++ * @returns {Spy} ++ */ ++ spyOn: function(obj, methodName) { ++ return env.spyOn(obj, methodName); ++ }, ++ ++ /** ++ * Install a spy on a property installed with `Object.defineProperty` onto an existing object. ++ * @name spyOnProperty ++ * @since 2.6.0 ++ * @function ++ * @global ++ * @param {Object} obj - The object upon which to install the {@link Spy} ++ * @param {String} propertyName - The name of the property to replace with a {@link Spy}. ++ * @param {String} [accessType=get] - The access type (get|set) of the property to {@link Spy} on. ++ * @returns {Spy} ++ */ ++ spyOnProperty: function(obj, methodName, accessType) { ++ return env.spyOnProperty(obj, methodName, accessType); ++ }, ++ ++ /** ++ * Installs spies on all writable and configurable properties of an object. ++ * @name spyOnAllFunctions ++ * @since 3.2.1 ++ * @function ++ * @global ++ * @param {Object} obj - The object upon which to install the {@link Spy}s ++ * @param {boolean} includeNonEnumerable - Whether or not to add spies to non-enumerable properties ++ * @returns {Object} the spied object ++ */ ++ spyOnAllFunctions: function(obj, includeNonEnumerable) { ++ return env.spyOnAllFunctions(obj, includeNonEnumerable); ++ }, ++ ++ jsApiReporter: new jasmine.JsApiReporter({ ++ timer: new jasmine.Timer() ++ }), ++ ++ /** ++ * @namespace jasmine ++ */ ++ jasmine: jasmine ++ }; ++ ++ /** ++ * Add a custom equality tester for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.addCustomEqualityTester ++ * @since 2.0.0 ++ * @function ++ * @param {Function} tester - A function which takes two arguments to compare and returns a `true` or `false` comparison result if it knows how to compare them, and `undefined` otherwise. ++ * @see custom_equality ++ */ ++ jasmine.addCustomEqualityTester = function(tester) { ++ env.addCustomEqualityTester(tester); ++ }; ++ ++ /** ++ * Add custom matchers for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.addMatchers ++ * @since 2.0.0 ++ * @function ++ * @param {Object} matchers - Keys from this object will be the new matcher names. ++ * @see custom_matcher ++ */ ++ jasmine.addMatchers = function(matchers) { ++ return env.addMatchers(matchers); ++ }; ++ ++ /** ++ * Add custom async matchers for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.addAsyncMatchers ++ * @since 3.5.0 ++ * @function ++ * @param {Object} matchers - Keys from this object will be the new async matcher names. ++ * @see custom_matcher ++ */ ++ jasmine.addAsyncMatchers = function(matchers) { ++ return env.addAsyncMatchers(matchers); ++ }; ++ ++ /** ++ * Add a custom object formatter for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.addCustomObjectFormatter ++ * @since 3.6.0 ++ * @function ++ * @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise. ++ * @see custom_object_formatters ++ */ ++ jasmine.addCustomObjectFormatter = function(formatter) { ++ return env.addCustomObjectFormatter(formatter); ++ }; ++ ++ /** ++ * Get the currently booted mock {Clock} for this Jasmine environment. ++ * @name jasmine.clock ++ * @since 2.0.0 ++ * @function ++ * @returns {Clock} ++ */ ++ jasmine.clock = function() { ++ return env.clock; ++ }; ++ ++ /** ++ * Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it. ++ * @name jasmine.createSpy ++ * @since 1.3.0 ++ * @function ++ * @param {String} [name] - Name to give the spy. This will be displayed in failure messages. ++ * @param {Function} [originalFn] - Function to act as the real implementation. ++ * @return {Spy} ++ */ ++ jasmine.createSpy = function(name, originalFn) { ++ return env.createSpy(name, originalFn); ++ }; ++ ++ /** ++ * Create an object with multiple {@link Spy}s as its members. ++ * @name jasmine.createSpyObj ++ * @since 1.3.0 ++ * @function ++ * @param {String} [baseName] - Base name for the spies in the object. ++ * @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}. ++ * @param {String[]|Object} [propertyNames] - Array of property names to create spies for, or Object whose keys will be propertynames and values the {@link Spy#and#returnValue|returnValue}. ++ * @return {Object} ++ */ ++ jasmine.createSpyObj = function(baseName, methodNames, propertyNames) { ++ return env.createSpyObj(baseName, methodNames, propertyNames); ++ }; ++ ++ /** ++ * Add a custom spy strategy for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.addSpyStrategy ++ * @since 3.5.0 ++ * @function ++ * @param {String} name - The name of the strategy (i.e. what you call from `and`) ++ * @param {Function} factory - Factory function that returns the plan to be executed. ++ */ ++ jasmine.addSpyStrategy = function(name, factory) { ++ return env.addSpyStrategy(name, factory); ++ }; ++ ++ /** ++ * Set the default spy strategy for the current scope of specs. ++ * ++ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}. ++ * @name jasmine.setDefaultSpyStrategy ++ * @function ++ * @param {Function} defaultStrategyFn - a function that assigns a strategy ++ * @example ++ * beforeEach(function() { ++ * jasmine.setDefaultSpyStrategy(and => and.returnValue(true)); ++ * }); ++ */ ++ jasmine.setDefaultSpyStrategy = function(defaultStrategyFn) { ++ return env.setDefaultSpyStrategy(defaultStrategyFn); ++ }; ++ ++ return jasmineInterface; ++}; ++ ++getJasmineRequireObj().Spy = function(j$) { ++ var nextOrder = (function() { ++ var order = 0; ++ ++ return function() { ++ return order++; ++ }; ++ })(); ++ ++ var matchersUtil = new j$.MatchersUtil({ ++ customTesters: [], ++ pp: j$.makePrettyPrinter() ++ }); ++ ++ /** ++ * @classdesc _Note:_ Do not construct this directly. Use {@link spyOn}, ++ * {@link spyOnProperty}, {@link jasmine.createSpy}, or ++ * {@link jasmine.createSpyObj} instead. ++ * @class Spy ++ * @hideconstructor ++ */ ++ function Spy( ++ name, ++ originalFn, ++ customStrategies, ++ defaultStrategyFn, ++ getPromise ++ ) { ++ var numArgs = typeof originalFn === 'function' ? originalFn.length : 0, ++ wrapper = makeFunc(numArgs, function(context, args, invokeNew) { ++ return spy(context, args, invokeNew); ++ }), ++ strategyDispatcher = new SpyStrategyDispatcher({ ++ name: name, ++ fn: originalFn, ++ getSpy: function() { ++ return wrapper; ++ }, ++ customStrategies: customStrategies, ++ getPromise: getPromise ++ }), ++ callTracker = new j$.CallTracker(), ++ spy = function(context, args, invokeNew) { ++ /** ++ * @name Spy.callData ++ * @property {object} object - `this` context for the invocation. ++ * @property {number} invocationOrder - Order of the invocation. ++ * @property {Array} args - The arguments passed for this invocation. ++ * @property returnValue - The value that was returned from this invocation. ++ */ ++ var callData = { ++ object: context, ++ invocationOrder: nextOrder(), ++ args: Array.prototype.slice.apply(args) ++ }; ++ ++ callTracker.track(callData); ++ var returnValue = strategyDispatcher.exec(context, args, invokeNew); ++ callData.returnValue = returnValue; ++ ++ return returnValue; ++ }; ++ ++ function makeFunc(length, fn) { ++ switch (length) { ++ case 1: ++ return function wrap1(a) { ++ return fn(this, arguments, this instanceof wrap1); ++ }; ++ case 2: ++ return function wrap2(a, b) { ++ return fn(this, arguments, this instanceof wrap2); ++ }; ++ case 3: ++ return function wrap3(a, b, c) { ++ return fn(this, arguments, this instanceof wrap3); ++ }; ++ case 4: ++ return function wrap4(a, b, c, d) { ++ return fn(this, arguments, this instanceof wrap4); ++ }; ++ case 5: ++ return function wrap5(a, b, c, d, e) { ++ return fn(this, arguments, this instanceof wrap5); ++ }; ++ case 6: ++ return function wrap6(a, b, c, d, e, f) { ++ return fn(this, arguments, this instanceof wrap6); ++ }; ++ case 7: ++ return function wrap7(a, b, c, d, e, f, g) { ++ return fn(this, arguments, this instanceof wrap7); ++ }; ++ case 8: ++ return function wrap8(a, b, c, d, e, f, g, h) { ++ return fn(this, arguments, this instanceof wrap8); ++ }; ++ case 9: ++ return function wrap9(a, b, c, d, e, f, g, h, i) { ++ return fn(this, arguments, this instanceof wrap9); ++ }; ++ default: ++ return function wrap() { ++ return fn(this, arguments, this instanceof wrap); ++ }; ++ } ++ } ++ ++ for (var prop in originalFn) { ++ if (prop === 'and' || prop === 'calls') { ++ throw new Error( ++ "Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon" ++ ); ++ } ++ ++ wrapper[prop] = originalFn[prop]; ++ } ++ ++ /** ++ * @member {SpyStrategy} - Accesses the default strategy for the spy. This strategy will be used ++ * whenever the spy is called with arguments that don't match any strategy ++ * created with {@link Spy#withArgs}. ++ * @name Spy#and ++ * @since 2.0.0 ++ * @example ++ * spyOn(someObj, 'func').and.returnValue(42); ++ */ ++ wrapper.and = strategyDispatcher.and; ++ /** ++ * Specifies a strategy to be used for calls to the spy that have the ++ * specified arguments. ++ * @name Spy#withArgs ++ * @since 3.0.0 ++ * @function ++ * @param {...*} args - The arguments to match ++ * @type {SpyStrategy} ++ * @example ++ * spyOn(someObj, 'func').withArgs(1, 2, 3).and.returnValue(42); ++ * someObj.func(1, 2, 3); // returns 42 ++ */ ++ wrapper.withArgs = function() { ++ return strategyDispatcher.withArgs.apply(strategyDispatcher, arguments); ++ }; ++ wrapper.calls = callTracker; ++ ++ if (defaultStrategyFn) { ++ defaultStrategyFn(wrapper.and); ++ } ++ ++ return wrapper; ++ } ++ ++ function SpyStrategyDispatcher(strategyArgs) { ++ var baseStrategy = new j$.SpyStrategy(strategyArgs); ++ var argsStrategies = new StrategyDict(function() { ++ return new j$.SpyStrategy(strategyArgs); ++ }); ++ ++ this.and = baseStrategy; ++ ++ this.exec = function(spy, args, invokeNew) { ++ var strategy = argsStrategies.get(args); ++ ++ if (!strategy) { ++ if (argsStrategies.any() && !baseStrategy.isConfigured()) { ++ throw new Error( ++ "Spy '" + ++ strategyArgs.name + ++ "' received a call with arguments " + ++ j$.pp(Array.prototype.slice.call(args)) + ++ ' but all configured strategies specify other arguments.' ++ ); ++ } else { ++ strategy = baseStrategy; ++ } ++ } ++ ++ return strategy.exec(spy, args, invokeNew); ++ }; ++ ++ this.withArgs = function() { ++ return { and: argsStrategies.getOrCreate(arguments) }; ++ }; ++ } ++ ++ function StrategyDict(strategyFactory) { ++ this.strategies = []; ++ this.strategyFactory = strategyFactory; ++ } ++ ++ StrategyDict.prototype.any = function() { ++ return this.strategies.length > 0; ++ }; ++ ++ StrategyDict.prototype.getOrCreate = function(args) { ++ var strategy = this.get(args); ++ ++ if (!strategy) { ++ strategy = this.strategyFactory(); ++ this.strategies.push({ ++ args: args, ++ strategy: strategy ++ }); ++ } ++ ++ return strategy; ++ }; ++ ++ StrategyDict.prototype.get = function(args) { ++ var i; ++ ++ for (i = 0; i < this.strategies.length; i++) { ++ if (matchersUtil.equals(args, this.strategies[i].args)) { ++ return this.strategies[i].strategy; ++ } ++ } ++ }; ++ ++ return Spy; ++}; ++ ++getJasmineRequireObj().SpyFactory = function(j$) { ++ function SpyFactory(getCustomStrategies, getDefaultStrategyFn, getPromise) { ++ var self = this; ++ ++ this.createSpy = function(name, originalFn) { ++ return j$.Spy( ++ name, ++ originalFn, ++ getCustomStrategies(), ++ getDefaultStrategyFn(), ++ getPromise ++ ); ++ }; ++ ++ this.createSpyObj = function(baseName, methodNames, propertyNames) { ++ var baseNameIsCollection = ++ j$.isObject_(baseName) || j$.isArray_(baseName); ++ ++ if (baseNameIsCollection) { ++ propertyNames = methodNames; ++ methodNames = baseName; ++ baseName = 'unknown'; ++ } ++ ++ var obj = {}; ++ var spy, descriptor; ++ ++ var methods = normalizeKeyValues(methodNames); ++ for (var i = 0; i < methods.length; i++) { ++ spy = obj[methods[i][0]] = self.createSpy( ++ baseName + '.' + methods[i][0] ++ ); ++ if (methods[i].length > 1) { ++ spy.and.returnValue(methods[i][1]); ++ } ++ } ++ ++ var properties = normalizeKeyValues(propertyNames); ++ for (var i = 0; i < properties.length; i++) { ++ descriptor = { ++ enumerable: true, ++ get: self.createSpy(baseName + '.' + properties[i][0] + '.get'), ++ set: self.createSpy(baseName + '.' + properties[i][0] + '.set') ++ }; ++ if (properties[i].length > 1) { ++ descriptor.get.and.returnValue(properties[i][1]); ++ descriptor.set.and.returnValue(properties[i][1]); ++ } ++ Object.defineProperty(obj, properties[i][0], descriptor); ++ } ++ ++ if (methods.length === 0 && properties.length === 0) { ++ throw 'createSpyObj requires a non-empty array or object of method names to create spies for'; ++ } ++ ++ return obj; ++ }; ++ } ++ ++ function normalizeKeyValues(object) { ++ var result = []; ++ if (j$.isArray_(object)) { ++ for (var i = 0; i < object.length; i++) { ++ result.push([object[i]]); ++ } ++ } else if (j$.isObject_(object)) { ++ for (var key in object) { ++ if (object.hasOwnProperty(key)) { ++ result.push([key, object[key]]); ++ } ++ } ++ } ++ return result; ++ } ++ ++ return SpyFactory; ++}; ++ ++getJasmineRequireObj().SpyRegistry = function(j$) { ++ var spyOnMsg = j$.formatErrorMsg('', 'spyOn(, )'); ++ var spyOnPropertyMsg = j$.formatErrorMsg( ++ '', ++ 'spyOnProperty(, , [accessType])' ++ ); ++ ++ function SpyRegistry(options) { ++ options = options || {}; ++ var global = options.global || j$.getGlobal(); ++ var createSpy = options.createSpy; ++ var currentSpies = ++ options.currentSpies || ++ function() { ++ return []; ++ }; ++ ++ this.allowRespy = function(allow) { ++ this.respy = allow; ++ }; ++ ++ this.spyOn = function(obj, methodName) { ++ var getErrorMsg = spyOnMsg; ++ ++ if (j$.util.isUndefined(obj) || obj === null) { ++ throw new Error( ++ getErrorMsg( ++ 'could not find an object to spy upon for ' + methodName + '()' ++ ) ++ ); ++ } ++ ++ if (j$.util.isUndefined(methodName) || methodName === null) { ++ throw new Error(getErrorMsg('No method name supplied')); ++ } ++ ++ if (j$.util.isUndefined(obj[methodName])) { ++ throw new Error(getErrorMsg(methodName + '() method does not exist')); ++ } ++ ++ if (obj[methodName] && j$.isSpy(obj[methodName])) { ++ if (this.respy) { ++ return obj[methodName]; ++ } else { ++ throw new Error( ++ getErrorMsg(methodName + ' has already been spied upon') ++ ); ++ } ++ } ++ ++ var descriptor = Object.getOwnPropertyDescriptor(obj, methodName); ++ ++ if (descriptor && !(descriptor.writable || descriptor.set)) { ++ throw new Error( ++ getErrorMsg(methodName + ' is not declared writable or has no setter') ++ ); ++ } ++ ++ var originalMethod = obj[methodName], ++ spiedMethod = createSpy(methodName, originalMethod), ++ restoreStrategy; ++ ++ if ( ++ Object.prototype.hasOwnProperty.call(obj, methodName) || ++ (obj === global && methodName === 'onerror') ++ ) { ++ restoreStrategy = function() { ++ obj[methodName] = originalMethod; ++ }; ++ } else { ++ restoreStrategy = function() { ++ if (!delete obj[methodName]) { ++ obj[methodName] = originalMethod; ++ } ++ }; ++ } ++ ++ currentSpies().push({ ++ restoreObjectToOriginalState: restoreStrategy ++ }); ++ ++ obj[methodName] = spiedMethod; ++ ++ return spiedMethod; ++ }; ++ ++ this.spyOnProperty = function(obj, propertyName, accessType) { ++ var getErrorMsg = spyOnPropertyMsg; ++ ++ accessType = accessType || 'get'; ++ ++ if (j$.util.isUndefined(obj)) { ++ throw new Error( ++ getErrorMsg( ++ 'spyOn could not find an object to spy upon for ' + ++ propertyName + ++ '' ++ ) ++ ); ++ } ++ ++ if (j$.util.isUndefined(propertyName)) { ++ throw new Error(getErrorMsg('No property name supplied')); ++ } ++ ++ var descriptor = j$.util.getPropertyDescriptor(obj, propertyName); ++ ++ if (!descriptor) { ++ throw new Error(getErrorMsg(propertyName + ' property does not exist')); ++ } ++ ++ if (!descriptor.configurable) { ++ throw new Error( ++ getErrorMsg(propertyName + ' is not declared configurable') ++ ); ++ } ++ ++ if (!descriptor[accessType]) { ++ throw new Error( ++ getErrorMsg( ++ 'Property ' + ++ propertyName + ++ ' does not have access type ' + ++ accessType ++ ) ++ ); ++ } ++ ++ if (j$.isSpy(descriptor[accessType])) { ++ if (this.respy) { ++ return descriptor[accessType]; ++ } else { ++ throw new Error( ++ getErrorMsg( ++ propertyName + '#' + accessType + ' has already been spied upon' ++ ) ++ ); ++ } ++ } ++ ++ var originalDescriptor = j$.util.clone(descriptor), ++ spy = createSpy(propertyName, descriptor[accessType]), ++ restoreStrategy; ++ ++ if (Object.prototype.hasOwnProperty.call(obj, propertyName)) { ++ restoreStrategy = function() { ++ Object.defineProperty(obj, propertyName, originalDescriptor); ++ }; ++ } else { ++ restoreStrategy = function() { ++ delete obj[propertyName]; ++ }; ++ } ++ ++ currentSpies().push({ ++ restoreObjectToOriginalState: restoreStrategy ++ }); ++ ++ descriptor[accessType] = spy; ++ ++ Object.defineProperty(obj, propertyName, descriptor); ++ ++ return spy; ++ }; ++ ++ this.spyOnAllFunctions = function(obj, includeNonEnumerable) { ++ if (j$.util.isUndefined(obj)) { ++ throw new Error( ++ 'spyOnAllFunctions could not find an object to spy upon' ++ ); ++ } ++ ++ var pointer = obj, ++ propsToSpyOn = [], ++ properties, ++ propertiesToSkip = []; ++ ++ while ( ++ pointer && ++ (!includeNonEnumerable || pointer !== Object.prototype) ++ ) { ++ properties = getProps(pointer, includeNonEnumerable); ++ properties = properties.filter(function(prop) { ++ return propertiesToSkip.indexOf(prop) === -1; ++ }); ++ propertiesToSkip = propertiesToSkip.concat(properties); ++ propsToSpyOn = propsToSpyOn.concat( ++ getSpyableFunctionProps(pointer, properties) ++ ); ++ pointer = Object.getPrototypeOf(pointer); ++ } ++ ++ for (var i = 0; i < propsToSpyOn.length; i++) { ++ this.spyOn(obj, propsToSpyOn[i]); ++ } ++ ++ return obj; ++ }; ++ ++ this.clearSpies = function() { ++ var spies = currentSpies(); ++ for (var i = spies.length - 1; i >= 0; i--) { ++ var spyEntry = spies[i]; ++ spyEntry.restoreObjectToOriginalState(); ++ } ++ }; ++ } ++ ++ function getProps(obj, includeNonEnumerable) { ++ var enumerableProperties = Object.keys(obj); ++ ++ if (!includeNonEnumerable) { ++ return enumerableProperties; ++ } ++ ++ return Object.getOwnPropertyNames(obj).filter(function(prop) { ++ return ( ++ prop !== 'constructor' || ++ enumerableProperties.indexOf('constructor') > -1 ++ ); ++ }); ++ } ++ ++ function getSpyableFunctionProps(obj, propertiesToCheck) { ++ var props = [], ++ prop; ++ for (var i = 0; i < propertiesToCheck.length; i++) { ++ prop = propertiesToCheck[i]; ++ if ( ++ Object.prototype.hasOwnProperty.call(obj, prop) && ++ isSpyableProp(obj, prop) ++ ) { ++ props.push(prop); ++ } ++ } ++ return props; ++ } ++ ++ function isSpyableProp(obj, prop) { ++ var value, descriptor; ++ try { ++ value = obj[prop]; ++ } catch (e) { ++ return false; ++ } ++ if (value instanceof Function) { ++ descriptor = Object.getOwnPropertyDescriptor(obj, prop); ++ return (descriptor.writable || descriptor.set) && descriptor.configurable; ++ } ++ return false; ++ } ++ ++ return SpyRegistry; ++}; ++ ++getJasmineRequireObj().SpyStrategy = function(j$) { ++ /** ++ * @interface SpyStrategy ++ */ ++ function SpyStrategy(options) { ++ options = options || {}; ++ ++ var self = this; ++ ++ /** ++ * Get the identifying information for the spy. ++ * @name SpyStrategy#identity ++ * @since 3.0.0 ++ * @member ++ * @type {String} ++ */ ++ this.identity = options.name || 'unknown'; ++ this.originalFn = options.fn || function() {}; ++ this.getSpy = options.getSpy || function() {}; ++ this.plan = this._defaultPlan = function() {}; ++ ++ var k, ++ cs = options.customStrategies || {}; ++ for (k in cs) { ++ if (j$.util.has(cs, k) && !this[k]) { ++ this[k] = createCustomPlan(cs[k]); ++ } ++ } ++ ++ var getPromise = ++ typeof options.getPromise === 'function' ++ ? options.getPromise ++ : function() {}; ++ ++ var requirePromise = function(name) { ++ var Promise = getPromise(); ++ ++ if (!Promise) { ++ throw new Error( ++ name + ++ ' requires global Promise, or `Promise` configured with `jasmine.getEnv().configure()`' ++ ); ++ } ++ ++ return Promise; ++ }; ++ ++ /** ++ * Tell the spy to return a promise resolving to the specified value when invoked. ++ * @name SpyStrategy#resolveTo ++ * @since 3.5.0 ++ * @function ++ * @param {*} value The value to return. ++ */ ++ this.resolveTo = function(value) { ++ var Promise = requirePromise('resolveTo'); ++ self.plan = function() { ++ return Promise.resolve(value); ++ }; ++ return self.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to return a promise rejecting with the specified value when invoked. ++ * @name SpyStrategy#rejectWith ++ * @since 3.5.0 ++ * @function ++ * @param {*} value The value to return. ++ */ ++ this.rejectWith = function(value) { ++ var Promise = requirePromise('rejectWith'); ++ ++ self.plan = function() { ++ return Promise.reject(value); ++ }; ++ return self.getSpy(); ++ }; ++ } ++ ++ function createCustomPlan(factory) { ++ return function() { ++ var plan = factory.apply(null, arguments); ++ ++ if (!j$.isFunction_(plan)) { ++ throw new Error('Spy strategy must return a function'); ++ } ++ ++ this.plan = plan; ++ return this.getSpy(); ++ }; ++ } ++ ++ /** ++ * Execute the current spy strategy. ++ * @name SpyStrategy#exec ++ * @since 2.0.0 ++ * @function ++ */ ++ SpyStrategy.prototype.exec = function(context, args, invokeNew) { ++ var contextArgs = [context].concat( ++ args ? Array.prototype.slice.call(args) : [] ++ ); ++ var target = this.plan.bind.apply(this.plan, contextArgs); ++ ++ return invokeNew ? new target() : target(); ++ }; ++ ++ /** ++ * Tell the spy to call through to the real implementation when invoked. ++ * @name SpyStrategy#callThrough ++ * @since 2.0.0 ++ * @function ++ */ ++ SpyStrategy.prototype.callThrough = function() { ++ this.plan = this.originalFn; ++ return this.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to return the value when invoked. ++ * @name SpyStrategy#returnValue ++ * @since 2.0.0 ++ * @function ++ * @param {*} value The value to return. ++ */ ++ SpyStrategy.prototype.returnValue = function(value) { ++ this.plan = function() { ++ return value; ++ }; ++ return this.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to return one of the specified values (sequentially) each time the spy is invoked. ++ * @name SpyStrategy#returnValues ++ * @since 2.1.0 ++ * @function ++ * @param {...*} values - Values to be returned on subsequent calls to the spy. ++ */ ++ SpyStrategy.prototype.returnValues = function() { ++ var values = Array.prototype.slice.call(arguments); ++ this.plan = function() { ++ return values.shift(); ++ }; ++ return this.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to throw an error when invoked. ++ * @name SpyStrategy#throwError ++ * @since 2.0.0 ++ * @function ++ * @param {Error|Object|String} something Thing to throw ++ */ ++ SpyStrategy.prototype.throwError = function(something) { ++ var error = j$.isString_(something) ? new Error(something) : something; ++ this.plan = function() { ++ throw error; ++ }; ++ return this.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to call a fake implementation when invoked. ++ * @name SpyStrategy#callFake ++ * @since 2.0.0 ++ * @function ++ * @param {Function} fn The function to invoke with the passed parameters. ++ */ ++ SpyStrategy.prototype.callFake = function(fn) { ++ if ( ++ !( ++ j$.isFunction_(fn) || ++ j$.isAsyncFunction_(fn) || ++ j$.isGeneratorFunction_(fn) ++ ) ++ ) { ++ throw new Error( ++ 'Argument passed to callFake should be a function, got ' + fn ++ ); ++ } ++ this.plan = fn; ++ return this.getSpy(); ++ }; ++ ++ /** ++ * Tell the spy to do nothing when invoked. This is the default. ++ * @name SpyStrategy#stub ++ * @since 2.0.0 ++ * @function ++ */ ++ SpyStrategy.prototype.stub = function(fn) { ++ this.plan = function() {}; ++ return this.getSpy(); ++ }; ++ ++ SpyStrategy.prototype.isConfigured = function() { ++ return this.plan !== this._defaultPlan; ++ }; ++ ++ return SpyStrategy; ++}; ++ ++getJasmineRequireObj().StackTrace = function(j$) { ++ function StackTrace(error) { ++ var lines = error.stack.split('\n').filter(function(line) { ++ return line !== ''; ++ }); ++ ++ var extractResult = extractMessage(error.message, lines); ++ ++ if (extractResult) { ++ this.message = extractResult.message; ++ lines = extractResult.remainder; ++ } ++ ++ var parseResult = tryParseFrames(lines); ++ this.frames = parseResult.frames; ++ this.style = parseResult.style; ++ } ++ ++ var framePatterns = [ ++ // PhantomJS on Linux, Node, Chrome, IE, Edge ++ // e.g. " at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)" ++ // Note that the "function name" can include a surprisingly large set of ++ // characters, including angle brackets and square brackets. ++ { ++ re: /^\s*at ([^\)]+) \(([^\)]+)\)$/, ++ fnIx: 1, ++ fileLineColIx: 2, ++ style: 'v8' ++ }, ++ ++ // NodeJS alternate form, often mixed in with the Chrome style ++ // e.g. " at /some/path:4320:20 ++ { re: /\s*at (.+)$/, fileLineColIx: 1, style: 'v8' }, ++ ++ // PhantomJS on OS X, Safari, Firefox ++ // e.g. "run@http://localhost:8888/__jasmine__/jasmine.js:4320:27" ++ // or "http://localhost:8888/__jasmine__/jasmine.js:4320:27" ++ { ++ re: /^(([^@\s]+)@)?([^\s]+)$/, ++ fnIx: 2, ++ fileLineColIx: 3, ++ style: 'webkit' ++ } ++ ]; ++ ++ // regexes should capture the function name (if any) as group 1 ++ // and the file, line, and column as group 2. ++ function tryParseFrames(lines) { ++ var style = null; ++ var frames = lines.map(function(line) { ++ var convertedLine = first(framePatterns, function(pattern) { ++ var overallMatch = line.match(pattern.re), ++ fileLineColMatch; ++ if (!overallMatch) { ++ return null; ++ } ++ ++ fileLineColMatch = overallMatch[pattern.fileLineColIx].match( ++ /^(.*):(\d+):\d+$/ ++ ); ++ if (!fileLineColMatch) { ++ return null; ++ } ++ ++ style = style || pattern.style; ++ return { ++ raw: line, ++ file: fileLineColMatch[1], ++ line: parseInt(fileLineColMatch[2], 10), ++ func: overallMatch[pattern.fnIx] ++ }; ++ }); ++ ++ return convertedLine || { raw: line }; ++ }); ++ ++ return { ++ style: style, ++ frames: frames ++ }; ++ } ++ ++ function first(items, fn) { ++ var i, result; ++ ++ for (i = 0; i < items.length; i++) { ++ result = fn(items[i]); ++ ++ if (result) { ++ return result; ++ } ++ } ++ } ++ ++ function extractMessage(message, stackLines) { ++ var len = messagePrefixLength(message, stackLines); ++ ++ if (len > 0) { ++ return { ++ message: stackLines.slice(0, len).join('\n'), ++ remainder: stackLines.slice(len) ++ }; ++ } ++ } ++ ++ function messagePrefixLength(message, stackLines) { ++ if (!stackLines[0].match(/^\w*Error/)) { ++ return 0; ++ } ++ ++ var messageLines = message.split('\n'); ++ var i; ++ ++ for (i = 1; i < messageLines.length; i++) { ++ if (messageLines[i] !== stackLines[i]) { ++ return 0; ++ } ++ } ++ ++ return messageLines.length; ++ } ++ ++ return StackTrace; ++}; ++ ++getJasmineRequireObj().Suite = function(j$) { ++ /** ++ * @interface Suite ++ * @see Env#topSuite ++ * @since 2.0.0 ++ */ ++ function Suite(attrs) { ++ this.env = attrs.env; ++ /** ++ * The unique ID of this suite. ++ * @name Suite#id ++ * @readonly ++ * @type {string} ++ * @since 2.0.0 ++ */ ++ this.id = attrs.id; ++ /** ++ * The parent of this suite, or null if this is the top suite. ++ * @name Suite#parentSuite ++ * @readonly ++ * @type {Suite} ++ */ ++ this.parentSuite = attrs.parentSuite; ++ /** ++ * The description passed to the {@link describe} that created this suite. ++ * @name Suite#description ++ * @readonly ++ * @type {string} ++ * @since 2.0.0 ++ */ ++ this.description = attrs.description; ++ this.expectationFactory = attrs.expectationFactory; ++ this.asyncExpectationFactory = attrs.asyncExpectationFactory; ++ this.expectationResultFactory = attrs.expectationResultFactory; ++ this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; ++ this.autoCleanClosures = ++ attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures; ++ ++ this.beforeFns = []; ++ this.afterFns = []; ++ this.beforeAllFns = []; ++ this.afterAllFns = []; ++ ++ this.timer = attrs.timer || new j$.Timer(); ++ ++ /** ++ * The suite's children. ++ * @name Suite#children ++ * @type {Array.<(Spec|Suite)>} ++ * @since 2.0.0 ++ */ ++ this.children = []; ++ ++ this.reset(); ++ } ++ ++ Suite.prototype.setSuiteProperty = function(key, value) { ++ this.result.properties = this.result.properties || {}; ++ this.result.properties[key] = value; ++ }; ++ ++ Suite.prototype.expect = function(actual) { ++ return this.expectationFactory(actual, this); ++ }; ++ ++ Suite.prototype.expectAsync = function(actual) { ++ return this.asyncExpectationFactory(actual, this); ++ }; ++ ++ /** ++ * The full description including all ancestors of this suite. ++ * @name Suite#getFullName ++ * @function ++ * @returns {string} ++ * @since 2.0.0 ++ */ ++ Suite.prototype.getFullName = function() { ++ var fullName = []; ++ for ( ++ var parentSuite = this; ++ parentSuite; ++ parentSuite = parentSuite.parentSuite ++ ) { ++ if (parentSuite.parentSuite) { ++ fullName.unshift(parentSuite.description); ++ } ++ } ++ return fullName.join(' '); ++ }; ++ ++ /* ++ * Mark the suite with "pending" status ++ */ ++ Suite.prototype.pend = function() { ++ this.markedPending = true; ++ }; ++ ++ /* ++ * Like {@link Suite#pend}, but pending state will survive {@link Spec#reset} ++ * Useful for fdescribe, xdescribe, where pending state should remain. ++ */ ++ Suite.prototype.exclude = function() { ++ this.pend(); ++ this.markedExcluding = true; ++ }; ++ ++ Suite.prototype.beforeEach = function(fn) { ++ this.beforeFns.unshift(fn); ++ }; ++ ++ Suite.prototype.beforeAll = function(fn) { ++ this.beforeAllFns.push(fn); ++ }; ++ ++ Suite.prototype.afterEach = function(fn) { ++ this.afterFns.unshift(fn); ++ }; ++ ++ Suite.prototype.afterAll = function(fn) { ++ this.afterAllFns.unshift(fn); ++ }; ++ ++ Suite.prototype.startTimer = function() { ++ this.timer.start(); ++ }; ++ ++ Suite.prototype.endTimer = function() { ++ this.result.duration = this.timer.elapsed(); ++ }; ++ ++ function removeFns(queueableFns) { ++ for (var i = 0; i < queueableFns.length; i++) { ++ queueableFns[i].fn = null; ++ } ++ } ++ ++ Suite.prototype.cleanupBeforeAfter = function() { ++ if (this.autoCleanClosures) { ++ removeFns(this.beforeAllFns); ++ removeFns(this.afterAllFns); ++ removeFns(this.beforeFns); ++ removeFns(this.afterFns); ++ } ++ }; ++ ++ Suite.prototype.reset = function() { ++ /** ++ * @typedef SuiteResult ++ * @property {Int} id - The unique id of this suite. ++ * @property {String} description - The description text passed to the {@link describe} that made this suite. ++ * @property {String} fullName - The full description including all ancestors of this suite. ++ * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite. ++ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite. ++ * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite. ++ * @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach. ++ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty} ++ * @since 2.0.0 ++ */ ++ this.result = { ++ id: this.id, ++ description: this.description, ++ fullName: this.getFullName(), ++ failedExpectations: [], ++ deprecationWarnings: [], ++ duration: null, ++ properties: null ++ }; ++ this.markedPending = this.markedExcluding; ++ this.children.forEach(function(child) { ++ child.reset(); ++ }); ++ }; ++ ++ Suite.prototype.addChild = function(child) { ++ this.children.push(child); ++ }; ++ ++ Suite.prototype.status = function() { ++ if (this.markedPending) { ++ return 'pending'; ++ } ++ ++ if (this.result.failedExpectations.length > 0) { ++ return 'failed'; ++ } else { ++ return 'passed'; ++ } ++ }; ++ ++ Suite.prototype.canBeReentered = function() { ++ return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; ++ }; ++ ++ Suite.prototype.getResult = function() { ++ this.result.status = this.status(); ++ return this.result; ++ }; ++ ++ Suite.prototype.sharedUserContext = function() { ++ if (!this.sharedContext) { ++ this.sharedContext = this.parentSuite ++ ? this.parentSuite.clonedSharedUserContext() ++ : new j$.UserContext(); ++ } ++ ++ return this.sharedContext; ++ }; ++ ++ Suite.prototype.clonedSharedUserContext = function() { ++ return j$.UserContext.fromExisting(this.sharedUserContext()); ++ }; ++ ++ Suite.prototype.onException = function() { ++ if (arguments[0] instanceof j$.errors.ExpectationFailed) { ++ return; ++ } ++ ++ var data = { ++ matcherName: '', ++ passed: false, ++ expected: '', ++ actual: '', ++ error: arguments[0] ++ }; ++ var failedExpectation = this.expectationResultFactory(data); ++ ++ if (!this.parentSuite) { ++ failedExpectation.globalErrorType = 'afterAll'; ++ } ++ ++ this.result.failedExpectations.push(failedExpectation); ++ }; ++ ++ Suite.prototype.addExpectationResult = function() { ++ if (isFailure(arguments)) { ++ var data = arguments[1]; ++ this.result.failedExpectations.push(this.expectationResultFactory(data)); ++ if (this.throwOnExpectationFailure) { ++ throw new j$.errors.ExpectationFailed(); ++ } ++ } ++ }; ++ ++ Suite.prototype.addDeprecationWarning = function(deprecation) { ++ if (typeof deprecation === 'string') { ++ deprecation = { message: deprecation }; ++ } ++ this.result.deprecationWarnings.push( ++ this.expectationResultFactory(deprecation) ++ ); ++ }; ++ ++ function isFailure(args) { ++ return !args[0]; ++ } ++ ++ return Suite; ++}; ++ ++if (typeof window == void 0 && typeof exports == 'object') { ++ /* globals exports */ ++ exports.Suite = jasmineRequire.Suite; ++} ++ ++getJasmineRequireObj().Timer = function() { ++ var defaultNow = (function(Date) { ++ return function() { ++ return new Date().getTime(); ++ }; ++ })(Date); ++ ++ function Timer(options) { ++ options = options || {}; ++ ++ var now = options.now || defaultNow, ++ startTime; ++ ++ this.start = function() { ++ startTime = now(); ++ }; ++ ++ this.elapsed = function() { ++ return now() - startTime; ++ }; ++ } ++ ++ return Timer; ++}; ++ ++getJasmineRequireObj().TreeProcessor = function() { ++ function TreeProcessor(attrs) { ++ var tree = attrs.tree, ++ runnableIds = attrs.runnableIds, ++ queueRunnerFactory = attrs.queueRunnerFactory, ++ nodeStart = attrs.nodeStart || function() {}, ++ nodeComplete = attrs.nodeComplete || function() {}, ++ failSpecWithNoExpectations = !!attrs.failSpecWithNoExpectations, ++ orderChildren = ++ attrs.orderChildren || ++ function(node) { ++ return node.children; ++ }, ++ excludeNode = ++ attrs.excludeNode || ++ function(node) { ++ return false; ++ }, ++ stats = { valid: true }, ++ processed = false, ++ defaultMin = Infinity, ++ defaultMax = 1 - Infinity; ++ ++ this.processTree = function() { ++ processNode(tree, true); ++ processed = true; ++ return stats; ++ }; ++ ++ this.execute = function(done) { ++ if (!processed) { ++ this.processTree(); ++ } ++ ++ if (!stats.valid) { ++ throw 'invalid order'; ++ } ++ ++ var childFns = wrapChildren(tree, 0); ++ ++ queueRunnerFactory({ ++ queueableFns: childFns, ++ userContext: tree.sharedUserContext(), ++ onException: function() { ++ tree.onException.apply(tree, arguments); ++ }, ++ onComplete: done ++ }); ++ }; ++ ++ function runnableIndex(id) { ++ for (var i = 0; i < runnableIds.length; i++) { ++ if (runnableIds[i] === id) { ++ return i; ++ } ++ } ++ } ++ ++ function processNode(node, parentExcluded) { ++ var executableIndex = runnableIndex(node.id); ++ ++ if (executableIndex !== undefined) { ++ parentExcluded = false; ++ } ++ ++ if (!node.children) { ++ var excluded = parentExcluded || excludeNode(node); ++ stats[node.id] = { ++ excluded: excluded, ++ willExecute: !excluded && !node.markedPending, ++ segments: [ ++ { ++ index: 0, ++ owner: node, ++ nodes: [node], ++ min: startingMin(executableIndex), ++ max: startingMax(executableIndex) ++ } ++ ] ++ }; ++ } else { ++ var hasExecutableChild = false; ++ ++ var orderedChildren = orderChildren(node); ++ ++ for (var i = 0; i < orderedChildren.length; i++) { ++ var child = orderedChildren[i]; ++ ++ processNode(child, parentExcluded); ++ ++ if (!stats.valid) { ++ return; ++ } ++ ++ var childStats = stats[child.id]; ++ ++ hasExecutableChild = hasExecutableChild || childStats.willExecute; ++ } ++ ++ stats[node.id] = { ++ excluded: parentExcluded, ++ willExecute: hasExecutableChild ++ }; ++ ++ segmentChildren(node, orderedChildren, stats[node.id], executableIndex); ++ ++ if (!node.canBeReentered() && stats[node.id].segments.length > 1) { ++ stats = { valid: false }; ++ } ++ } ++ } ++ ++ function startingMin(executableIndex) { ++ return executableIndex === undefined ? defaultMin : executableIndex; ++ } ++ ++ function startingMax(executableIndex) { ++ return executableIndex === undefined ? defaultMax : executableIndex; ++ } ++ ++ function segmentChildren( ++ node, ++ orderedChildren, ++ nodeStats, ++ executableIndex ++ ) { ++ var currentSegment = { ++ index: 0, ++ owner: node, ++ nodes: [], ++ min: startingMin(executableIndex), ++ max: startingMax(executableIndex) ++ }, ++ result = [currentSegment], ++ lastMax = defaultMax, ++ orderedChildSegments = orderChildSegments(orderedChildren); ++ ++ function isSegmentBoundary(minIndex) { ++ return ( ++ lastMax !== defaultMax && ++ minIndex !== defaultMin && ++ lastMax < minIndex - 1 ++ ); ++ } ++ ++ for (var i = 0; i < orderedChildSegments.length; i++) { ++ var childSegment = orderedChildSegments[i], ++ maxIndex = childSegment.max, ++ minIndex = childSegment.min; ++ ++ if (isSegmentBoundary(minIndex)) { ++ currentSegment = { ++ index: result.length, ++ owner: node, ++ nodes: [], ++ min: defaultMin, ++ max: defaultMax ++ }; ++ result.push(currentSegment); ++ } ++ ++ currentSegment.nodes.push(childSegment); ++ currentSegment.min = Math.min(currentSegment.min, minIndex); ++ currentSegment.max = Math.max(currentSegment.max, maxIndex); ++ lastMax = maxIndex; ++ } ++ ++ nodeStats.segments = result; ++ } ++ ++ function orderChildSegments(children) { ++ var specifiedOrder = [], ++ unspecifiedOrder = []; ++ ++ for (var i = 0; i < children.length; i++) { ++ var child = children[i], ++ segments = stats[child.id].segments; ++ ++ for (var j = 0; j < segments.length; j++) { ++ var seg = segments[j]; ++ ++ if (seg.min === defaultMin) { ++ unspecifiedOrder.push(seg); ++ } else { ++ specifiedOrder.push(seg); ++ } ++ } ++ } ++ ++ specifiedOrder.sort(function(a, b) { ++ return a.min - b.min; ++ }); ++ ++ return specifiedOrder.concat(unspecifiedOrder); ++ } ++ ++ function executeNode(node, segmentNumber) { ++ if (node.children) { ++ return { ++ fn: function(done) { ++ var onStart = { ++ fn: function(next) { ++ nodeStart(node, next); ++ } ++ }; ++ ++ queueRunnerFactory({ ++ onComplete: function() { ++ var args = Array.prototype.slice.call(arguments, [0]); ++ node.cleanupBeforeAfter(); ++ nodeComplete(node, node.getResult(), function() { ++ done.apply(undefined, args); ++ }); ++ }, ++ queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)), ++ userContext: node.sharedUserContext(), ++ onException: function() { ++ node.onException.apply(node, arguments); ++ } ++ }); ++ } ++ }; ++ } else { ++ return { ++ fn: function(done) { ++ node.execute( ++ done, ++ stats[node.id].excluded, ++ failSpecWithNoExpectations ++ ); ++ } ++ }; ++ } ++ } ++ ++ function wrapChildren(node, segmentNumber) { ++ var result = [], ++ segmentChildren = stats[node.id].segments[segmentNumber].nodes; ++ ++ for (var i = 0; i < segmentChildren.length; i++) { ++ result.push( ++ executeNode(segmentChildren[i].owner, segmentChildren[i].index) ++ ); ++ } ++ ++ if (!stats[node.id].willExecute) { ++ return result; ++ } ++ ++ return node.beforeAllFns.concat(result).concat(node.afterAllFns); ++ } ++ } ++ ++ return TreeProcessor; ++}; ++ ++getJasmineRequireObj().UserContext = function(j$) { ++ function UserContext() {} ++ ++ UserContext.fromExisting = function(oldContext) { ++ var context = new UserContext(); ++ ++ for (var prop in oldContext) { ++ if (oldContext.hasOwnProperty(prop)) { ++ context[prop] = oldContext[prop]; ++ } ++ } ++ ++ return context; ++ }; ++ ++ return UserContext; ++}; ++ ++getJasmineRequireObj().version = function() { ++ return '3.10.1'; ++}; diff --cc subprojects/jasmine-gjs/lib/local-modifications.patch index 000000000,000000000..c902dc8cb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/lib/local-modifications.patch @@@ -1,0 -1,0 +1,34 @@@ ++--- jasmine.js.orig 2024-01-20 15:06:20.821078800 +0100 +++++ jasmine.js 2024-01-20 15:07:10.360495593 +0100 ++@@ -1,3 +1,4 @@ +++/* jscs:disable */ ++ /* ++ Copyright (c) 2008-2021 Pivotal Labs ++ ++@@ -319,7 +320,7 @@ ++ }; ++ ++ j$.isAsymmetricEqualityTester_ = function(obj) { ++- return obj ? j$.isA_('Function', obj.asymmetricMatch) : false; +++ return obj?.asymmetricMatch ? j$.isA_('Function', obj.asymmetricMatch) : false; ++ }; ++ ++ j$.getType_ = function(value) { ++@@ -581,7 +582,7 @@ ++ * @return {Boolean} ++ */ ++ j$.isSpy = function(putativeSpy) { ++- if (!putativeSpy) { +++ if (!putativeSpy || !putativeSpy.and) { ++ return false; ++ } ++ return ( ++@@ -2249,7 +2250,7 @@ ++ }; ++ ++ this.describe = function(description, specDefinitions) { ++- ensureIsNotNested('describe'); +++ //ensureIsNotNested('describe'); ++ ensureIsFunction(specDefinitions, 'describe'); ++ var suite = suiteFactory(description); ++ if (specDefinitions.length > 0) { diff --cc subprojects/jasmine-gjs/lib/update-jasmine.sh index 000000000,000000000..7abbbd221 new file mode 100755 --- /dev/null +++ b/subprojects/jasmine-gjs/lib/update-jasmine.sh @@@ -1,0 -1,0 +1,5 @@@ ++# This script is used to build our custom version of the Jasmine library by ++# downloading the upstream file and applying our patches, and is meant for use ++# only when upgrading to a new upstream version. ++curl -o jasmine.js https://raw.githubusercontent.com/jasmine/jasmine/v3.10.1/lib/jasmine-core/jasmine.js ++patch = 0.58.0') ++ ++gjs_dep = dependency('gjs-1.0', required: false) ++if gjs_dep.found() ++ gjs = find_program(gjs_dep.get_variable('gjs_console')) ++else ++ gjs = find_program('gjs', 'gjs-console') ++endif ++ ++pkglibexecdir = join_paths(get_option('libexecdir'), meson.project_name()) ++pkgdatadir = join_paths(get_option('datadir'), meson.project_name()) ++jasmine_mod = meson.project_name() ++ ++uninstalled_pkglibexecdir = meson.current_build_dir() ++uninstalled_pkgdatadir = join_paths(meson.current_source_dir(), 'src') ++uninstalled_jasmine_mod = 'lib' ++ ++# Executables ++ ++config = configuration_data() ++if meson.is_subproject() ++ config.set('pkgdatadir', uninstalled_pkgdatadir) ++ config.set('pkglibexecdir', uninstalled_pkglibexecdir) ++ config.set('jasmine_mod', uninstalled_jasmine_mod) ++else ++ config.set('pkgdatadir', join_paths(get_option('prefix'), pkgdatadir)) ++ config.set('pkglibexecdir', join_paths(get_option('prefix'), pkglibexecdir)) ++ config.set('jasmine_mod', jasmine_mod) ++endif ++config.set('PACKAGE_VERSION', meson.project_version()) ++ ++jasmine = configure_file(configuration: config, input: 'bin/jasmine.in', ++ output: 'jasmine', install: not meson.is_subproject(), install_dir: 'bin') ++ ++jasmine_runner = configure_file(configuration: config, ++ input: 'bin/jasmine-runner.in', output: 'jasmine-runner', ++ install: not meson.is_subproject(), ++ install_dir: pkglibexecdir) ++ ++meson.override_find_program('jasmine', jasmine) ++ ++# Source code and Jasmine library ++ ++if not meson.is_subproject() ++ install_data( ++ 'lib/jasmine.js', ++ 'src/command.js', ++ 'src/config.js', ++ 'src/consoleReporter.js', ++ 'src/jasmineBoot.js', ++ 'src/junitReporter.js', ++ 'src/options.js', ++ 'src/tapReporter.js', ++ 'src/timer.js', ++ 'src/utils.js', ++ 'src/verboseReporter.js', ++ 'src/xmlWriter.js', ++ install_dir: pkgdatadir, ++ ) ++endif ++ ++# Documentation ++ ++if not meson.is_subproject() ++ install_data('jasmine.man', rename: 'jasmine.1', ++ install_dir: join_paths(get_option('datadir'), 'man', 'man1')) ++endif ++ ++# Tests ++ ++tests = [ ++ 'commandSpec', ++ 'configSpec', ++ 'consoleReporterSpec', ++ 'defaultReporterSpec', ++ 'focusedSpecIntegrationTest', ++ 'importerSpec', ++ 'jasmineBootSpec', ++ 'jasmineIntegrationTest', ++ 'junitReporterSpec', ++ 'optionsSpec', ++ 'tapReporterSpec', ++ 'timerSpec', ++ 'utilsSpec', ++ 'verboseReporterSpec', ++ 'xmlWriterSpec', ++] ++if not meson.is_subproject() ++ test_env = environment() ++ test_env.set('TEST_PKGDATADIR', uninstalled_pkgdatadir) ++ test_env.set('TEST_PKGLIBEXECDIR', uninstalled_pkglibexecdir) ++ test_env.set('TEST_JASMINE_MOD', uninstalled_jasmine_mod) ++ foreach t : tests ++ test_file = files('test/@0@.js'.format(t)) ++ test(t, gjs, args: ['-m', jasmine, test_file, '--module', '--tap', '--no-config'], ++ env: test_env, protocol: 'tap') ++ endforeach ++endif diff --cc subprojects/jasmine-gjs/release-checklist.md index 000000000,000000000..c638e6427 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/release-checklist.md @@@ -1,0 -1,0 +1,57 @@@ ++# Release Checklist # ++ ++## Updating to a new upstream release ## ++ ++- [ ] Bump version in `meson.build`. ++- [ ] Change upstream Jasmine version in the `lib/update-jasmine.sh` script. ++- [ ] Delete `lib/jasmine.js`. ++- [ ] Run `cd lib; ./update-jasmine.sh` to regenerate `lib/jasmine.js` from the new upstream version. ++- [ ] Resolve patch conflicts with the new upstream version if necessary. ++- [ ] If making a new major release, update `test/jasmineIntegrationTest.js` and `test/focusedSpecIntegrationTest.js` from `https://github.com/jasmine/jasmine.github.io/tree/master/_versions//src`. ++ Currently we use `introduction.js`, `custom_equality.js`, `custom_matcher.js`, and `focused_specs.js`, but there may be new features that should be included as well. ++ Strip the documentation comments and the weird indentation. ++- [ ] If making a new major release, see if there are any new features that we can use to improve jasmine-gjs's own tests. ++- [ ] Run `meson test`. ++- [ ] Make a commit. ++- [ ] Write release notes in `NEWS.md`. ++ ++## Packaging: RPM ## ++ ++- [ ] Update the version number in `jasmine-gjs.spec`. ++- [ ] Add a changelog entry in `jasmine-gjs.spec`. ++- [ ] Make any other necessary changes to `jasmine-gjs.spec`. ++- [ ] Run `ninja dist`. ++- [ ] Copy `jasmine-gjs-.tar.xz` to `rpmbuild/SOURCES`. ++- [ ] Copy `jasmine-gjs.spec` to `rpmbuild/SPECS`. ++- [ ] Run `rpmbuild -ba /path/to/rpmbuild/SPECS/jasmine-gjs.spec` to ensure that everything builds OK. ++- [ ] Make a commit. ++ ++## Packaging: Debian ## ++ ++- [ ] Update the changelog with `dch`. (Distribution = `unstable`) ++- [ ] Make any other necessary changes to the `debian` directory. ++- [ ] Run `debuild -uc -us -b` to ensure that everything builds OK. ++- [ ] Make a commit. ++- [ ] Run `ninja dist`. ++- [ ] Copy `jasmine-gjs-.tar.xz` to `../jasmine-gjs_.orig.tar.xz`. ++- [ ] Extract the tarball. ++- [ ] Enter the directory and run `debuild -uc -us -S` to build a source package. ++ ++## Releasing: OBS ## ++ ++- [ ] On [OBS](https://build.opensuse.org/project/repositories/home:ptomato), check if repositories should be enabled for any new Fedora, Ubuntu, Debian, or OpenSUSE distribution releases. ++- [ ] Copy `jasmine-gjs-.tar.xz`, `jasmine-gjs.spec`, `jasmine-gjs_.orig.tar.xz`, `jasmine-gjs_-1.debian.tar.xz`, and `jasmine-gjs_-1.dsc` into an OBS checkout of the `home:ptomato/jasmine-gjs` project. ++- [ ] Remove the files in the OBS checkout that are from the previous version. ++- [ ] Run `osc addremove`. ++- [ ] Run `osc commit`. ++- [ ] Check that all builds passed. ++ ++## Releasing: Other ## ++ ++- [ ] Add `jasmine-gjs-.tar.xz` to the `downloads` directory in the `ptomato/ptomato.github.com` repository. ++- [ ] Modify `opensource/jasmine/jasmine.md` to point to the newest version. ++- [ ] Make a commit. ++- [ ] Back in the `jasmine-gjs` repository, run `git tag `; version is just dotted numbers, e.g. `2.2.1`, no `v` or `Version`. ++- [ ] Push the tag to GitHub. ++- [ ] Copy the release notes from `NEWS.md` into https://github.com/ptomato/jasmine-gjs/releases ++- [ ] Attach the tarball and the sha256sum from the `meson-dist` directory to the release notes. diff --cc subprojects/jasmine-gjs/src/command.js index 000000000,000000000..9f42a0180 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/command.js @@@ -1,0 -1,0 +1,113 @@@ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++import * as Options from './options.js'; ++import * as Timer from './timer.js'; ++import * as JUnitReporter from './junitReporter.js'; ++import * as VerboseReporter from './verboseReporter.js'; ++import * as TapReporter from './tapReporter.js'; ++import * as ConsoleReporter from './consoleReporter.js'; ++ ++export const mainloop = GLib.MainLoop.new(null, false); ++ ++export async function run(_jasmine, argv, timeout = -1) { ++ const [files, options] = Options.parseOptions(argv); ++ ++ if (options.exclude) ++ _jasmine.exclusions = options.exclude; ++ ++ if (options.module) ++ _jasmine.module = true; ++ ++ if (options.junit) { ++ let junitPath = options.junit; ++ if (!GLib.path_is_absolute(junitPath) && ++ GLib.getenv('JASMINE_JUNIT_REPORTS_DIR') !== null) ++ junitPath = `${GLib.getenv('JASMINE_JUNIT_REPORTS_DIR')}/${junitPath}`; ++ const junitFile = Gio.File.new_for_commandline_arg(junitPath); ++ ++ // Since people might want their report dir structure to mirror ++ // their test dir structure, we shall be kind and try to create any ++ // report directories that don't exist. ++ try { ++ junitFile.get_parent().make_directory_with_parents(null); ++ } catch (e) { ++ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) ++ throw e; ++ // ignore error if directory already exists ++ } ++ ++ const rawStream = junitFile.replace(null, false, Gio.FileCreateFlags.NONE, null); ++ const junitStream = new Gio.DataOutputStream({ ++ base_stream: rawStream, ++ }); ++ ++ const junitReporter = new JUnitReporter.JUnitReporter({ ++ timerFactory: Timer.createDefaultTimer, ++ print(str) { ++ junitStream.put_string(str, null); ++ }, ++ }); ++ junitReporter.connect('complete', () => junitStream.close(null)); ++ _jasmine.addReporter(junitReporter); ++ } ++ ++ let timeoutId; ++ const reporterOptions = { ++ show_colors: options.color, ++ timerFactory: Timer.createDefaultTimer, ++ }; ++ let exitCode = 0; ++ ++ let reporter; ++ if (options.verbose) ++ reporter = new VerboseReporter.VerboseReporter(reporterOptions); ++ else if (options.tap) ++ reporter = new TapReporter.TapReporter(reporterOptions); ++ else ++ reporter = new ConsoleReporter.DefaultReporter(reporterOptions); ++ ++ reporter.connect('started', () => GLib.source_remove(timeoutId)); ++ reporter.connect('complete', (_, success) => { ++ if (!success) ++ exitCode = 1; ++ mainloop.quit(); ++ }); ++ _jasmine.addReporter(reporter); ++ ++ // This works around a limitation in GJS 1.40 where exceptions occurring ++ // during module import are swallowed. ++ if (timeout !== -1) { ++ timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, timeout, function () { ++ if (options.tap) ++ print('Bail out! Test suite failed to start within 10 seconds'); ++ else ++ printerr('Test suite failed to start within 10 seconds'); ++ exitCode = 1; ++ mainloop.quit(); ++ }); ++ } ++ ++ // This should start after the main loop starts, otherwise we will hit ++ // Mainloop.run() only after several tests have already run. For consistency ++ // we should guarantee that there is a main loop running during the tests. ++ GLib.idle_add(GLib.PRIORITY_DEFAULT, function () { ++ _jasmine.execute(files).catch(e => { ++ if (options.tap) { ++ // "Bail out!" has a special meaning to TAP harnesses ++ print('Bail out! Exception occurred inside Jasmine:', e); ++ } else { ++ printerr('Exception occurred inside Jasmine:'); ++ printerr(e); ++ printerr(e.stack); ++ } ++ exitCode = 1; ++ mainloop.quit(); ++ }); ++ return GLib.SOURCE_REMOVE; ++ }); ++ ++ // _jasmine.execute() queues up all the tests and runs them asynchronously. ++ await mainloop.runAsync(); ++ return exitCode; ++} diff --cc subprojects/jasmine-gjs/src/config.js index 000000000,000000000..f2eae16ea new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/config.js @@@ -1,0 -1,0 +1,142 @@@ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++function _makePathsAbsolute(configFile, paths) { ++ return paths.map(path => { ++ if (GLib.path_is_absolute(path)) ++ return path; ++ return configFile.get_parent().resolve_relative_path(path).get_path(); ++ }); ++} ++ ++// Make it legal to specify "some_option": "single_value" in the config file as ++// well as "some_option": ["multiple", "values"] ++export function ensureArray(option) { ++ if (!Array.isArray(option)) ++ return [option]; ++ return option; ++} ++ ++export function loadConfig(options, defaultFile = 'jasmine.json') { ++ if (options['no-config']) ++ return {}; ++ ++ let config = {}; ++ const configFile = Gio.File.new_for_commandline_arg(options.config || defaultFile); ++ ++ try { ++ let [, contents] = configFile.load_contents(null); ++ if (contents instanceof Uint8Array) ++ contents = imports.byteArray.toString(contents); ++ config = JSON.parse(contents); ++ } catch (e) { ++ if (!options.config && e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) ++ return {}; // Don't complain if config file absent from default location ++ throw new Error(`Configuration not read from ${configFile.get_path()}`); ++ } ++ ++ if (config.include_paths) { ++ config.include_paths = _makePathsAbsolute(configFile, ++ ensureArray(config.include_paths)); ++ } ++ if (config.spec_files) { ++ config.spec_files = _makePathsAbsolute(configFile, ++ ensureArray(config.spec_files)); ++ } ++ ++ const RECOGNIZED_KEYS = [ ++ 'environment', ++ 'exclude', ++ 'include_paths', ++ 'interpreter', ++ 'options', ++ 'spec_files', ++ ]; ++ Object.keys(config).forEach(key => { ++ if (RECOGNIZED_KEYS.indexOf(key) === -1) ++ printerr(`warning: unrecognized config file key "${key}"`); ++ }); ++ ++ print('Configuration loaded from', configFile.get_path()); ++ return config; ++} ++ ++function optionsToArgs(options) { ++ const args = [options.color ? '--color' : '--no-color']; ++ if (options.verbose) ++ args.push('--verbose'); ++ if (options.module) ++ args.push('--module'); ++ if (options.tap) ++ args.push('--tap'); ++ if (options.junit) { ++ args.push('--junit'); ++ args.push(options.junit); ++ } ++ if (options.exclude) { ++ ensureArray(options.exclude).forEach(exclude => { ++ args.push('--exclude'); ++ args.push(exclude); ++ }); ++ } ++ return args; ++} ++ ++export function configToArgs(config, specFiles = [], options = {}) { ++ let retval = []; ++ if (config.exclude) { ++ ensureArray(config.exclude).forEach(exclude => { ++ retval.push('--exclude'); ++ retval.push(exclude); ++ }); ++ } ++ ++ // Command-line options should always override config file options ++ if (config.options) ++ retval = retval.concat(ensureArray(config.options)); ++ retval = retval.concat(optionsToArgs(options), specFiles); ++ // Specific tests given on the command line should always override the ++ // default tests in the config file ++ if (specFiles.length === 0 && config.spec_files) ++ retval = retval.concat(ensureArray(config.spec_files)); ++ ++ return retval; ++} ++ ++export function prepareLauncher(config, options = {}) { ++ let flags = Gio.SubprocessFlags.NONE; ++ if (options.debug) ++ flags |= Gio.SubprocessFlags.STDIN_INHERIT; ++ const launcher = new Gio.SubprocessLauncher({flags}); ++ if (config.environment) { ++ Object.keys(config.environment).forEach(key => { ++ if (config.environment[key] === null) ++ launcher.unsetenv(key); ++ else ++ launcher.setenv(key, config.environment[key], true); ++ }); ++ } ++ if (config.include_paths) { ++ const existingPaths = launcher.getenv('GJS_PATH'); ++ const paths = ensureArray(config.include_paths).slice(); ++ if (existingPaths) ++ paths.unshift(existingPaths); ++ launcher.setenv('GJS_PATH', paths.join(':'), /* overwrite = */ true); ++ } ++ return launcher; ++} ++ ++export function wrapArgs(args, config, options = {}) { ++ if (options.interpreter) ++ args.unshift(...options.interpreter.split(' ')); ++ else if (config.interpreter) ++ args.unshift(...config.interpreter.split(' ')); ++ else if (options.module) ++ args.push('--module'); ++ if (options.debug) { ++ if (!options.interpreter && !config.interpreter) ++ args.unshift('gjs', '-m'); ++ args.unshift(...options.debug.split(' ')); ++ } ++ return args; ++} diff --cc subprojects/jasmine-gjs/src/consoleReporter.js index 000000000,000000000..ac3db0073 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/consoleReporter.js @@@ -1,0 -1,0 +1,254 @@@ ++import Gio from 'gi://Gio'; ++import GObject from 'gi://GObject'; ++ ++import {indenter} from './utils.js'; ++ ++const YELLOW = '\x1b[33m'; ++const GREEN = '\x1b[32m'; ++const RED = '\x1b[31m'; ++const NORMAL = '\x1b[0m'; ++ ++function createNoopTimer() { ++ return { ++ start() {}, ++ elapsed() { ++ return 0; ++ }, ++ }; ++} ++ ++export const ConsoleReporter = GObject.registerClass({ ++ Properties: { ++ 'show-colors': GObject.ParamSpec.boolean('show-colors', 'Show colors', ++ 'Whether to print color output', ++ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ++ true), ++ 'jasmine-core-path': GObject.ParamSpec.string('jasmine-core-path', ++ 'Jasmine core path', ++ 'Path to Jasmine core module for stack trace purposes', ++ GObject.ParamFlags.READWRITE, ++ '/nowhere'), ++ }, ++ ++ Signals: { ++ 'started': {}, ++ 'complete': { ++ param_types: [GObject.TYPE_BOOLEAN], ++ }, ++ }, ++}, class ConsoleReporter extends GObject.Object { ++ _init(props = {}) { ++ if (props.hasOwnProperty('print')) { ++ this._print = props.print; ++ delete props.print; ++ } ++ ++ this._timerFactory = createNoopTimer; ++ if (props.hasOwnProperty('timerFactory')) { ++ this._timerFactory = props.timerFactory; ++ delete props.timerFactory; ++ } ++ ++ super._init(props); ++ ++ // The main timer should return 0 if the run hasn't started yet ++ this._timers = { ++ 'main': createNoopTimer(), ++ }; ++ ++ this._failedSpecs = []; ++ this._failedSuites = []; ++ this._suiteLevel = 0; ++ this._specCount = 0; ++ this._passingCount = 0; ++ this._failureCount = 0; ++ this._pendingCount = 0; ++ } ++ ++ _color(str, color) { ++ if (typeof color !== 'undefined') ++ return this.show_colors ? color + str + NORMAL : str; ++ return str; ++ } ++ ++ // default print function that prints to stdout (GJS' built-in print ++ // functions, print() and printerr(), unfortunately append newlines to ++ // everything) ++ static getStdout() { ++ if (!this._stdout) { ++ const FD_STDOUT = 1; ++ const fdstream = new Gio.UnixOutputStream({ ++ fd: FD_STDOUT, ++ close_fd: false, ++ }); ++ this._stdout = new Gio.DataOutputStream({ ++ base_stream: fdstream, ++ }); ++ } ++ return this._stdout; ++ } ++ ++ _print(str) { ++ ConsoleReporter.getStdout().put_string(str, null); ++ } ++ ++ // Used to start a timer associated with a particular ID. Subclasses can use ++ // this to time actions that the base class doesn't time if they wish. ++ startTimer(id) { ++ this._timers[id] = this._timerFactory(id); ++ this._timers[id].start(); ++ } ++ ++ // Used to get the elapsed time from a timer with the given ID. Subclasses ++ // can use this to time actions not timed by the base class. The base class ++ // uses timers with the following IDs: ++ // main - times the whole suite ++ // suite:foo - times the suite with ID "foo" ++ // spec:bar - times the spec with ID "bar" ++ elapsedTime(id) { ++ return this._timers[id].elapsed(); ++ } ++ ++ // Called with an "info" object with the following property: ++ // totalSpecsDefined - number of specs to be run ++ jasmineStarted() { ++ this.emit('started'); ++ this.startTimer('main'); ++ } ++ ++ jasmineDone() { ++ this.elapsedTime('main'); // Stop the timer ++ this.emit('complete', this._failureCount === 0); ++ } ++ ++ // Called with a "result" object with the following properties: ++ // id - a string unique to this suite ++ // description - the name of the suite passed to describe() ++ // fullName - the full name including the names of parent suites ++ // failedExpectations - a list of failures in this suite ++ suiteStarted(result) { ++ if (result.id) ++ this.startTimer(`suite:${result.id}`); ++ this._suiteLevel++; ++ } ++ ++ // Called with the same object as suiteStarted(), with an extra property: ++ // status - "disabled", "failed", or "finished" ++ // Adds another extra property if the suite was started properly with ID: ++ // time - time taken to execute the suite, in milliseconds ++ suiteDone(result) { ++ this._suiteLevel--; ++ if (result.failedExpectations && result.failedExpectations.length > 0) { ++ this._failureCount++; ++ this._failedSuites.push(result); ++ } ++ if (result.id) ++ result.time = this.elapsedTime(`suite:${result.id}`); ++ } ++ ++ // Called with a "result" object with the following properties: ++ // id - a string unique to this spec ++ // description: the name of the spec passed to it() ++ // fullName - the full name concatenated with the suite's full name ++ // failedExpectations - a list of failures in this spec ++ // passedExpectations - a list of succeeded expectations in this spec ++ specStarted(result) { ++ if (result.id) ++ this.startTimer(`spec:${result.id}`); ++ this._specCount++; ++ } ++ ++ // Called with the same object as specStarted(), with an extra property: ++ // status - "disabled", "pending", "failed", or "passed" ++ // Adds another extra property if the spec was started properly with ID: ++ // time - time taken to execute the spec, in milliseconds ++ specDone(result) { ++ if (result.status === 'passed') { ++ this._passingCount++; ++ } else if (result.status === 'pending') { ++ this._pendingCount++; ++ } else if (result.status === 'failed') { ++ this._failureCount++; ++ this._failedSpecs.push(result); ++ } ++ if (result.id) ++ result.time = this.elapsedTime(`spec:${result.id}`); ++ } ++ ++ filterStack(stack) { ++ return stack.split('\n').filter(stackLine => { ++ return stackLine.indexOf(this.jasmine_core_path) === -1; ++ }).join('\n'); ++ } ++}); ++ ++// This reporter has very nearly the same behaviour to Jasmine's default console ++// reporter. ++export const DefaultReporter = GObject.registerClass(class DefaultReporter extends ConsoleReporter { ++ jasmineStarted(info) { ++ super.jasmineStarted(info); ++ this._print('Started\n'); ++ } ++ ++ jasmineDone() { ++ this._print('\n\n'); ++ if (this._failedSpecs.length > 0) ++ this._print('Failures:'); ++ this._failedSpecs.forEach(this._printSpecFailureDetails, this); ++ ++ if (this._specCount > 0) { ++ this._print('\n'); ++ this._print(`${this._specCount} spec${this._specCount === 1 ? '' : 's'}, ${this._failureCount} failed`); ++ ++ if (this._pendingCount) ++ this._print(`, ${this._pendingCount} pending`); ++ } else { ++ this._print('No specs found'); ++ } ++ ++ this._print('\n'); ++ const seconds = Math.round(this.elapsedTime('main')) / 1000; ++ this._print(`\nFinished in ${seconds} s\n`); ++ ++ this._failedSuites.forEach(this._printSuiteFailureDetails, this); ++ ++ super.jasmineDone(); ++ } ++ ++ specDone(result) { ++ super.specDone(result); ++ ++ const colors = { ++ passed: GREEN, ++ pending: YELLOW, ++ failed: RED, ++ disabled: undefined, ++ }; ++ const symbols = { ++ passed: '.', ++ pending: '*', ++ failed: 'F', ++ disabled: '', ++ }; ++ this._print(this._color(symbols[result.status], colors[result.status])); ++ } ++ ++ _printSpecFailureDetails(result, index) { ++ this._print(`\n${index + 1}) ${result.fullName}\n`); ++ result.failedExpectations.forEach(failedExpectation => { ++ const report = `Message: ++${this._color(failedExpectation.message, RED)} ++Stack: ++${this.filterStack(failedExpectation.stack)} ++`; ++ this._print(indenter.indent(report, 2)); ++ }); ++ } ++ ++ _printSuiteFailureDetails(result) { ++ result.failedExpectations.forEach(failedExpectation => { ++ this._print(this._color(`An error was thrown in an afterAll ++AfterAll ${failedExpectation.message}`, RED)); ++ }); ++ } ++}); diff --cc subprojects/jasmine-gjs/src/jasmineBoot.js index 000000000,000000000..53e0a3d00 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/jasmineBoot.js @@@ -1,0 -1,0 +1,145 @@@ ++/* global jasmineImporter */ ++ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++export const Jasmine = class Jasmine { ++ constructor({jasmineCore} = {jasmineCore: jasmineImporter.jasmine}) { ++ const jasmineCorePath = jasmineCore.__file__; ++ this._jasmineCoreFile = Gio.File.new_for_path(jasmineCorePath); ++ ++ const jasmineRequire = jasmineCore.getJasmineRequireObj(); ++ this._jasmine = jasmineRequire.core(jasmineRequire); ++ this.env = this._jasmine.getEnv(); ++ this.env.configure({ ++ random: false, ++ }); ++ this._jasmineInterface = jasmineRequire.interface(this._jasmine, this.env); ++ ++ this.exclusions = []; ++ this.specFiles = []; ++ this.module = false; ++ this._reportersCount = 0; ++ } ++ ++ get version() { ++ return this._jasmine.version; ++ } ++ ++ addReporter(reporter) { ++ reporter.jasmine_core_path = this._jasmineCoreFile.get_parent().get_path(); ++ this.env.addReporter(reporter); ++ this._reportersCount++; ++ } ++ ++ _addSpecFile(file) { ++ const absolutePath = file.get_path(); ++ const shouldSkip = this.exclusions.some(pattern => { ++ // Match globs against the absolute path ++ if (GLib.pattern_match_simple(pattern, absolutePath)) ++ return true; ++ // Also match if the string matches at the end ++ if (GLib.pattern_match_simple(`*/${pattern}`, absolutePath)) ++ return true; ++ // Also match if the string matches the path at the end ++ return GLib.pattern_match_simple(`*/${pattern}`, ++ file.get_parent().get_path()); ++ }); ++ if (shouldSkip) ++ return; ++ if (this.specFiles.indexOf(absolutePath) === -1) ++ this.specFiles.push(absolutePath); ++ } ++ ++ addSpecFiles(filePaths) { ++ filePaths.forEach(filePath => { ++ const file = Gio.File.new_for_path(filePath); ++ const type = file.query_file_type(Gio.FileQueryInfoFlags.NONE, null); ++ ++ switch (type) { ++ case Gio.FileType.REGULAR: ++ case Gio.FileType.UNKNOWN: ++ this._addSpecFile(file); ++ break; ++ case Gio.FileType.DIRECTORY: ++ recurseDirectory(file, this._addSpecFile.bind(this)); ++ break; ++ default: ++ // ignore ++ } ++ }); ++ } ++ ++ async loadSpecs() { ++ await Promise.all(this.specFiles.map(async file => { ++ const oldSearchPath = imports.searchPath.slice(); // make a copy ++ let specImporter = imports['.']; ++ ++ const modulePath = GLib.path_get_dirname(file); ++ const moduleName = GLib.path_get_basename(file).slice(0, -3); // .js ++ ++ // Backwards compatibility - let specs import modules from their own ++ // directories ++ imports.searchPath.unshift(modulePath); ++ specImporter.searchPath.unshift(modulePath); ++ ++ try { ++ if (this.module) ++ await import(`file://${file}`); ++ else ++ await specImporter[moduleName]; ++ } catch (err) { ++ if (!(err instanceof SyntaxError || err.name === 'ImportError')) ++ throw err; ++ // Fake failing suite, to log a failure but continue on with ++ // other specs ++ globalThis.describe(file, function () { ++ globalThis.it('did not import correctly', function () { ++ let failureMessage; ++ if (err instanceof SyntaxError) { ++ const {fileName, lineNumber, columnNumber, message} = err; ++ failureMessage = `${fileName}:${lineNumber}:${columnNumber}: ${message}`; ++ } else { ++ failureMessage = err.message; ++ } ++ globalThis.fail(failureMessage); ++ }); ++ }); ++ } ++ imports.searchPath = oldSearchPath; ++ ++ // Make a new copy of the importer in case we need to import another ++ // spec with the same filename, so it is not cached ++ specImporter = specImporter['.']; ++ })); ++ } ++ ++ async execute(files) { ++ if (files && files.length > 0) ++ this.addSpecFiles(files); ++ ++ await this.loadSpecs(); ++ this.env.execute(); ++ } ++ ++ // Install Jasmine API on the global object ++ installAPI(global) { ++ Object.assign(global, this._jasmineInterface); ++ } ++}; ++ ++function recurseDirectory(directory, func) { ++ const enumerator = directory.enumerate_children('standard::*', ++ Gio.FileQueryInfoFlags.NONE, null); ++ ++ let info; ++ while ((info = enumerator.next_file(null))) { ++ const file = enumerator.get_child(info); ++ const filename = file.get_basename(); ++ ++ if (info.get_file_type() === Gio.FileType.DIRECTORY) ++ recurseDirectory(file, func); ++ else if (filename.endsWith('.js')) ++ func(file); ++ } ++} diff --cc subprojects/jasmine-gjs/src/junitReporter.js index 000000000,000000000..3d4a9a677 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/junitReporter.js @@@ -1,0 -1,0 +1,158 @@@ ++// Reporter that outputs a JUnit XML test report ++// See http://llg.cubic.org/docs/junit/ ++// Unfortunately, the JUnit format is woefully underspecified. ++ ++import GLib from 'gi://GLib'; ++import GObject from 'gi://GObject'; ++ ++import {ConsoleReporter} from './consoleReporter.js'; ++import * as XMLWriter from './xmlWriter.js'; ++ ++export const JUnitReporter = GObject.registerClass(class JUnitReporter extends ConsoleReporter { ++ jasmineStarted(info) { ++ this._currentSuite = null; ++ super.jasmineStarted(info); ++ this._tree = new XMLWriter.Node('testsuites'); ++ this._suiteCount = 0; ++ this._activeSuites = []; ++ ++ const properties = new XMLWriter.Node('properties'); ++ properties.children = GLib.listenv().map(key => { ++ const property = new XMLWriter.Node('property'); ++ property.attrs = { ++ name: key, ++ value: GLib.getenv(key), ++ }; ++ return property; ++ }); ++ this._tree.children.push(properties); ++ } ++ ++ jasmineDone() { ++ const failedAfterAlls = this._failedSuites.length; ++ if (failedAfterAlls > 0) { ++ const afterAllSuite = new XMLWriter.Node('testsuite'); ++ afterAllSuite.attrs = { ++ name: 'afterAll()', ++ tests: failedAfterAlls, ++ errors: failedAfterAlls, ++ id: this._suiteCount++, ++ }; ++ afterAllSuite.children = this._failedSuites.map(failure => { ++ const afterAllCase = new XMLWriter.Node('testcase'); ++ afterAllCase.attrs = { ++ name: failure.description, ++ classname: 'AfterAll', ++ assertions: failure.failedExpectations.length, ++ }; ++ afterAllCase.children = failure.failedExpectations.map(result => { ++ const error = new XMLWriter.Node('error'); ++ error.attrs = _parseExceptionMessage(result); ++ error.text = result.stack; ++ return error; ++ }); ++ return afterAllCase; ++ }); ++ this._tree.children.push(afterAllSuite); ++ } ++ ++ // Timer inherited from ConsoleReporter ++ this._tree.attrs = { ++ time: this.elapsedTime('main') / 1000, ++ }; ++ ++ this._print(this._tree.toString()); ++ ++ super.jasmineDone(); ++ } ++ ++ // Jenkins parses nested JUnit test suites but doesn't display them properly. ++ // See https://issues.jenkins-ci.org/browse/JENKINS-18673 ++ // Therefore, we flatten all suites into one level. ++ suiteStarted(result) { ++ super.suiteStarted(result); ++ this._activeSuites.push(this._currentSuite); ++ this._currentSuite = new XMLWriter.Node('testsuite'); ++ this._currentSuite.attrs = { ++ name: result.fullName, ++ id: this._suiteCount++, ++ tests: 0, ++ disabled: 0, ++ failures: 0, ++ errors: 0, ++ skipped: 0, ++ timestamp: GLib.DateTime.new_now_local().format('%Y-%m-%dT%H:%M:%S'), ++ }; ++ this._tree.children.push(this._currentSuite); ++ } ++ ++ suiteDone(result) { ++ super.suiteDone(result); ++ this._currentSuite.attrs.time = result.time / 1000; // in seconds ++ this._currentSuite = this._activeSuites.pop(); ++ } ++ ++ specStarted(result) { ++ super.specStarted(result); ++ this._currentSuite.attrs.tests++; ++ } ++ ++ specDone(result) { ++ super.specDone(result); ++ ++ const spec = new XMLWriter.Node('testcase'); ++ spec.attrs = { ++ name: result.description, ++ classname: this._currentSuite.attrs['name'], ++ assertions: result.failedExpectations.length + ++ result.passedExpectations.length, ++ time: result.time / 1000, // in seconds ++ }; ++ ++ switch (result.status) { ++ case 'disabled': ++ this._currentSuite.attrs.disabled++; ++ return; ++ case 'failed': { ++ // We count a failure as a "failure" if at least one expectation ++ // failed. If there were only uncaught exceptions, then it is an ++ // "error". ++ let assertFailed = false; ++ result.failedExpectations.forEach(failedExpectation => { ++ let node; ++ if (failedExpectation.matcherName !== '') { ++ assertFailed = true; ++ node = new XMLWriter.Node('failure'); ++ node.attrs = { ++ type: failedExpectation.matcherName, ++ message: failedExpectation.message, ++ }; ++ } else { ++ node = new XMLWriter.Node('error'); ++ node.attrs = _parseExceptionMessage(failedExpectation); ++ } ++ node.text = this.filterStack(failedExpectation.stack); ++ spec.children.push(node); ++ }); ++ if (assertFailed) ++ this._currentSuite.attrs.failures++; ++ else ++ this._currentSuite.attrs.errors++; ++ } ++ break; ++ case 'pending': ++ this._currentSuite.attrs.skipped++; ++ spec.children.push(new XMLWriter.Node('skipped')); ++ break; ++ } ++ this._currentSuite.children.push(spec); ++ } ++}); ++ ++function _parseExceptionMessage(expectation) { ++ const parse = expectation.message.split(':'); ++ return { ++ type: parse.length > 1 ? parse[0] : 'Error', ++ message: expectation.message, ++ }; ++} diff --cc subprojects/jasmine-gjs/src/options.js index 000000000,000000000..25d3b25bd new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/options.js @@@ -1,0 -1,0 +1,150 @@@ ++import * as System from 'system'; ++ ++const ARGS = { ++ 'help': { ++ help: 'show this help', ++ action: 'help', ++ }, ++ 'version': { ++ help: 'print program version', ++ action: 'store_true', ++ }, ++ 'no-color': { ++ help: 'turn off color in spec output', ++ dest: 'color', ++ action: 'store_false', ++ default: true, ++ }, ++ 'color': { ++ help: 'turn on color in spec output', ++ action: 'store_true', ++ }, ++ 'verbose': { ++ help: 'print verbose results (similar to mocha)', ++ action: 'store_true', ++ }, ++ 'tap': { ++ help: 'output results in TAP format', ++ action: 'store_true', ++ }, ++ 'junit': { ++ help: 'output a JUnit report to the given file [report.xml]', ++ action: 'store', ++ nargs: '?', ++ const: 'report.xml', ++ }, ++ 'config': { ++ help: 'load configuration from the given file', ++ action: 'store', ++ }, ++ 'no-config': { ++ help: 'ignore the default jasmine.json config file', ++ action: 'store_true', ++ }, ++ 'exclude': { ++ help: 'do not execute the given spec (may include wildcards)', ++ action: 'append', ++ }, ++ 'module': { ++ help: 'execute specs as module', ++ action: 'store_true', ++ }, ++ 'interpreter': { ++ help: 'run with the given program instead of /usr/bin/env gjs', ++ action: 'store', ++ }, ++ 'debug': { ++ help: 'run with a debugger [gdb --args]', ++ action: 'store', ++ nargs: '?', ++ const: 'gdb --args', ++ }, ++}; ++ ++export function parseOptions(argv) { ++ argv = argv.slice(); // Make a copy ++ const namespace = {}; ++ const files = []; ++ ++ Object.keys(ARGS).forEach(function (argName) { ++ const argInfo = ARGS[argName]; ++ const dest = argInfo.dest || argName; ++ if (typeof argInfo.default !== 'undefined') ++ namespace[dest] = argInfo.default; ++ }); ++ ++ let argvElement; ++ while ((argvElement = argv.shift())) { ++ if (!argvElement.startsWith('-')) { ++ files.push(argvElement); ++ continue; ++ } ++ ++ if (!argvElement.startsWith('--')) { ++ printerr(`warning: Unknown argument "${argvElement}"`); ++ continue; ++ } ++ const argName = argvElement.slice(2); ++ if (!(argName in ARGS)) { ++ printerr(`warning: Unknown argument "${argvElement}"`); ++ continue; ++ } ++ ++ const argInfo = ARGS[argName]; ++ const dest = argInfo.dest || argName; ++ let value; ++ switch (argInfo.action) { ++ case 'help': ++ help(); ++ break; ++ case 'store_true': ++ namespace[dest] = true; ++ break; ++ case 'store_false': ++ namespace[dest] = false; ++ break; ++ case 'store': ++ value = _getNextArgument(argv); ++ if (typeof value === 'undefined' && argInfo.nargs === '?') ++ value = argInfo.const; ++ if (typeof value === 'undefined') { ++ printerr(`warning: Missing value for argument "${argName}"`); ++ continue; ++ } ++ namespace[dest] = value; ++ break; ++ case 'append': ++ value = _getNextArgument(argv); ++ if (typeof value === 'undefined') { ++ printerr(`warning: Missing value for argument "${argName}"`); ++ continue; ++ } ++ if (!(dest in namespace)) ++ namespace[dest] = []; ++ namespace[dest].push(value); ++ break; ++ } ++ } ++ return [files, namespace]; ++} ++ ++function _getNextArgument(argv) { ++ let value = argv.shift(); ++ if (typeof value !== 'undefined' && value.startsWith('--')) { ++ argv.unshift(value); ++ value = undefined; ++ } ++ return value; ++} ++ ++function help() { ++ print('Usage: jasmine [-I ] [options] \n'); ++ print('If file given, runs the spec in that file. If directory given,'); ++ print('searches for and runs specs under that directory.\n'); ++ print('Options:'); ++ Object.keys(ARGS).forEach(function (argName) { ++ print(`${`--${argName}`.padStart(15)}\t\t${ARGS[argName].help}`); ++ }); ++ print(''); ++ System.exit(0); ++} diff --cc subprojects/jasmine-gjs/src/tapReporter.js index 000000000,000000000..08746cd77 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/tapReporter.js @@@ -1,0 -1,0 +1,72 @@@ ++// Reporter that outputs according to the Test Anything Protocol ++// See http://testanything.org/tap-specification.html ++ ++import GObject from 'gi://GObject'; ++ ++import {ConsoleReporter} from './consoleReporter.js'; ++ ++export const TapReporter = GObject.registerClass(class TapReporter extends ConsoleReporter { ++ jasmineStarted(info) { ++ super.jasmineStarted(info); ++ this._print(`1..${info.totalSpecsDefined}\n`); ++ } ++ ++ jasmineDone() { ++ this._failedSuites.forEach(failure => { ++ failure.failedExpectations.forEach(result => { ++ this._print(`not ok - An error was thrown in an afterAll(): ${result.message}\n`); ++ }); ++ }); ++ super.jasmineDone(); ++ } ++ ++ suiteStarted(result) { ++ super.suiteStarted(result); ++ this._print(`# Suite started: ${result.fullName}\n`); ++ } ++ ++ suiteDone(result) { ++ super.suiteDone(result); ++ if (result.status === 'disabled') { ++ this._print(`# Suite was disabled: ${result.fullName}\n`); ++ } else { ++ const failures = result.failedExpectations.length; ++ this._print(`# Suite finished with ${failures} failure${failures === 1 ? '' : 's'}: ${result.fullName}\n`); ++ } ++ } ++ ++ specDone(result) { ++ super.specDone(result); ++ ++ if (result.status === 'failed') ++ this._print('not ok'); ++ else ++ this._print('ok'); ++ this._print(` ${this._specCount} - ${result.fullName}`); ++ if (result.status === 'pending' || result.status === 'disabled') { ++ const reason = result.pendingReason || result.status; ++ this._print(` # SKIP ${reason}`); ++ } ++ if (result.status === 'failed' && result.failedExpectations) { ++ const messages = result.failedExpectations.map(r => _removeNewlines(r.message)).join(' '); ++ this._print(` (${messages})`); ++ } ++ this._print('\n'); ++ ++ // Print additional diagnostic info on failure ++ if (result.status === 'failed' && result.failedExpectations) { ++ result.failedExpectations.forEach(failedExpectation => { ++ this._print(`# Message: ${_removeNewlines(failedExpectation.message)}\n`); ++ this._print('# Stack:\n'); ++ const stackTrace = this.filterStack(failedExpectation.stack).trim(); ++ this._print(stackTrace.split('\n').map(str => `# ${str}`).join('\n')); ++ this._print('\n'); ++ }); ++ } ++ } ++}); ++ ++function _removeNewlines(str) { ++ const allNewlines = /\n/g; ++ return str.replace(allNewlines, '\\n'); ++} diff --cc subprojects/jasmine-gjs/src/timer.js index 000000000,000000000..6a5b78864 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/timer.js @@@ -1,0 -1,0 +1,16 @@@ ++import GLib from 'gi://GLib'; ++ ++// Measures elapsed time in milliseconds. ++export function createDefaultTimer() { ++ let startTime, elapsedTime; ++ return { ++ start() { ++ startTime = GLib.get_monotonic_time(); ++ }, ++ elapsed() { ++ if (!elapsedTime) ++ elapsedTime = (GLib.get_monotonic_time() - startTime) / 1000; ++ return elapsedTime; ++ }, ++ }; ++} diff --cc subprojects/jasmine-gjs/src/utils.js index 000000000,000000000..aee690532 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/utils.js @@@ -1,0 -1,0 +1,9 @@@ ++export const indenter = { ++ indent(str, spaces) { ++ return str.split('\n').map(line => { ++ if (line === '') ++ return line; ++ return ' '.repeat(spaces) + line; ++ }).join('\n'); ++ }, ++}; diff --cc subprojects/jasmine-gjs/src/verboseReporter.js index 000000000,000000000..c5a7ead80 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/verboseReporter.js @@@ -1,0 -1,0 +1,100 @@@ ++import GObject from 'gi://GObject'; ++ ++import {ConsoleReporter} from './consoleReporter.js'; ++import {indenter} from './utils.js'; ++ ++const GRAY = '\x1b[38;5;246m'; ++const YELLOW = '\x1b[33m'; ++const GREEN = '\x1b[32m'; ++const RED = '\x1b[31m'; ++ ++// This reporter, activated with --verbose on the command line, behaves very ++// similarly to Mocha's nicely formatted reporter. ++export const VerboseReporter = GObject.registerClass(class VerboseReporter extends ConsoleReporter { ++ jasmineStarted(info) { ++ super.jasmineStarted(info); ++ this._print('Started\n\n'); ++ } ++ ++ jasmineDone() { ++ this._print('\n'); ++ this._failedSpecs.forEach(this._printSpecFailureDetails, this); ++ const seconds = Math.round(this.elapsedTime('main')) / 1000; ++ ++ this._print(this._color(` ${this._passingCount} passing`, GREEN)); ++ this._print(` (${seconds} s)\n`); ++ if (this._pendingCount > 0) ++ this._print(this._color(` ${this._pendingCount} pending\n`, YELLOW)); ++ if (this._failureCount > 0) ++ this._print(this._color(` ${this._failureCount} failing\n`, RED)); ++ this._print('\n'); ++ ++ this._failedSuites.forEach(this._printSuiteFailureDetails, this); ++ ++ super.jasmineDone(); ++ } ++ ++ suiteStarted(result) { ++ super.suiteStarted(result); ++ this._print(indenter.indent(this._color(result.description, GRAY), ++ this._suiteLevel * 2)); ++ this._print('\n'); ++ } ++ ++ suiteDone(result) { ++ if (result.status === 'disabled') { ++ this._print(indenter.indent(`${this._color('(disabled)', YELLOW)}\n`, ++ this._suiteLevel * 2 + 2)); ++ } ++ ++ super.suiteDone(result); ++ ++ if (this._suiteLevel === 0) ++ this._print('\n'); ++ } ++ ++ specDone(result) { ++ super.specDone(result); ++ ++ const colors = { ++ passed: GREEN, ++ pending: YELLOW, ++ failed: RED, ++ disabled: undefined, ++ }; ++ const symbols = { ++ passed: '✓', ++ pending: '-', ++ failed: `${this._failureCount})`, ++ disabled: 'x', ++ }; ++ this._print(indenter.indent(this._color(symbols[result.status], ++ colors[result.status]), this._suiteLevel * 2 + 2)); ++ this._print(` ${result.description}`); ++ if (result.time > 75) ++ this._print(` ${this._color(`(${result.time} ms)`, RED)}`); ++ else if (result.time > 40) ++ this._print(` ${this._color(`(${result.time} ms)`, YELLOW)}`); ++ if (result.pendingReason) ++ this._print(` ${this._color(`(${result.pendingReason})`, YELLOW)}`); ++ this._print('\n'); ++ } ++ ++ _printSpecFailureDetails(result, index) { ++ this._print(this._color(`${index + 1}) ${result.fullName}\n\n`, RED)); ++ ++ result.failedExpectations.forEach(failedExpectation => { ++ this._print(indenter.indent(this._color(failedExpectation.message, GRAY), 2)); ++ this._print('\n'); ++ this._print(indenter.indent(this.filterStack(failedExpectation.stack), 4)); ++ this._print('\n\n'); ++ }); ++ } ++ ++ _printSuiteFailureDetails(result) { ++ result.failedExpectations.forEach(failedExpectation => { ++ this._print(this._color(`An error was thrown in an afterAll ++AfterAll ${failedExpectation.message}`, RED)); ++ }); ++ } ++}); diff --cc subprojects/jasmine-gjs/src/xmlWriter.js index 000000000,000000000..cce33a71f new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/src/xmlWriter.js @@@ -1,0 -1,0 +1,38 @@@ ++import GLib from 'gi://GLib'; ++ ++import {indenter} from './utils.js'; ++ ++export const Node = class Node { ++ constructor(name) { ++ this.name = name; ++ this.attrs = {}; ++ this.children = []; ++ this.text = ''; ++ } ++ ++ toString() { ++ return `\n${_prettyprint(this)}`; ++ } ++}; ++ ++function _attrsToString(attrs) { ++ return Object.keys(attrs).map(key => { ++ const value = attrs[key].toString(); ++ return ` ${key}="${GLib.markup_escape_text(value, -1)}"`; ++ }).join(''); ++} ++ ++function _prettyprint(node) { ++ if (node.children.length === 0 && node.text.length === 0) ++ return `<${node.name}${_attrsToString(node.attrs)}/>\n`; ++ ++ const elementTop = `<${node.name}${_attrsToString(node.attrs)}>\n`; ++ const elementBottom = `\n`; ++ const children = node.children.map(_prettyprint).join(''); ++ let text = GLib.markup_escape_text(node.text, -1).trim(); ++ if (text.length !== 0) ++ text += '\n'; ++ ++ return elementTop + indenter.indent(children, 2) + indenter.indent(text, 2) + ++ elementBottom; ++} diff --cc subprojects/jasmine-gjs/test/.eslintrc.yml index 000000000,000000000..14b7a033a new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/.eslintrc.yml @@@ -1,0 -1,0 +1,29 @@@ ++--- ++env: ++ jasmine: true ++rules: ++ no-restricted-globals: ++ - error ++ - name: fdescribe ++ message: Do not commit fdescribe(). Use describe() instead. ++ - name: fit ++ message: Do not commit fit(). Use it() instead. ++ no-restricted-syntax: ++ - error ++ - selector: CallExpression[callee.name="it"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++ - selector: CallExpression[callee.name="describe"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++ - selector: CallExpression[callee.name="beforeEach"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++ - selector: CallExpression[callee.name="afterEach"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++ - selector: CallExpression[callee.name="beforeAll"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++ - selector: CallExpression[callee.name="afterAll"] > ArrowFunctionExpression ++ message: Arrow functions can mess up some Jasmine APIs. Use function () instead ++globals: ++ clearInterval: writable ++ clearTimeout: writable ++ setInterval: writable ++ setTimeout: writable diff --cc subprojects/jasmine-gjs/test/commandSpec.js index 000000000,000000000..3456d7d30 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/commandSpec.js @@@ -1,0 -1,0 +1,124 @@@ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++import * as Command from '../src/command.js'; ++import * as JUnitReporter from '../src/junitReporter.js'; ++import * as TapReporter from '../src/tapReporter.js'; ++import * as VerboseReporter from '../src/verboseReporter.js'; ++ ++const {mainloop} = Command; ++ ++describe('Jasmine command', function () { ++ let fakeJasmine; ++ ++ beforeAll(function () { ++ Gio._promisify(Gio._LocalFilePrototype, 'delete_async', 'delete_finish'); ++ }); ++ ++ beforeEach(function () { ++ fakeJasmine = jasmine.createSpyObj('jasmine', ['addReporter', 'configureDefaultReporter', 'execute']); ++ spyOn(mainloop, 'runAsync'); // stub out system behaviour ++ }); ++ ++ describe('running specs', function () { ++ it('shows colors by default', function () { ++ Command.run(fakeJasmine, []); ++ expect(fakeJasmine.addReporter) ++ .toHaveBeenCalledWith(jasmine.objectContaining({show_colors: true})); ++ }); ++ ++ it('allows colors to be turned off', function () { ++ Command.run(fakeJasmine, ['--no-color']); ++ expect(fakeJasmine.addReporter) ++ .toHaveBeenCalledWith(jasmine.objectContaining({show_colors: false})); ++ }); ++ ++ it('lets later color arguments override earlier ones', function () { ++ Command.run(fakeJasmine, ['--color', '--no-color']); ++ expect(fakeJasmine.addReporter) ++ .toHaveBeenCalledWith(jasmine.objectContaining({show_colors: false})); ++ Command.run(fakeJasmine, ['--no-color', '--color']); ++ expect(fakeJasmine.addReporter) ++ .toHaveBeenCalledWith(jasmine.objectContaining({show_colors: true})); ++ }); ++ ++ it('loads the verbose reporter', function () { ++ Command.run(fakeJasmine, ['--verbose']); ++ expect(fakeJasmine.addReporter).toHaveBeenCalled(); ++ const [reporter] = fakeJasmine.addReporter.calls.argsFor(0); ++ expect(reporter.constructor).toBe(VerboseReporter.VerboseReporter); ++ }); ++ ++ it('loads the TAP reporter', function () { ++ Command.run(fakeJasmine, ['--tap']); ++ expect(fakeJasmine.addReporter).toHaveBeenCalled(); ++ const [reporter] = fakeJasmine.addReporter.calls.argsFor(0); ++ expect(reporter.constructor).toBe(TapReporter.TapReporter); ++ }); ++ ++ it('loads the JUnit reporter alongside the usual reporter', function () { ++ // Unfortunately /dev/null can't be opened as a GFile, so we need to ++ // write to a temporary file. ++ const [tmpFile, stream] = Gio.File.new_tmp('junitreportXXXXXX'); ++ const tmpPath = tmpFile.get_path(); ++ stream.close(null); ++ ++ Command.run(fakeJasmine, ['--junit', tmpPath]); ++ expect(fakeJasmine.addReporter.calls.count()).toBe(2); ++ const reporters = fakeJasmine.addReporter.calls.allArgs().map(args => args[0].constructor); ++ expect(reporters).toContain(JUnitReporter.JUnitReporter); ++ ++ tmpFile.delete_async(GLib.PRIORITY_DEFAULT, null).then(() => {}); ++ }); ++ ++ it('creates a directory for the report if necessary', function () { ++ const tmpDir = GLib.dir_make_tmp('junitreportXXXXXX'); ++ const tmpFile = ++ Gio.File.new_for_path(tmpDir).get_child('dir').get_child('report.xml'); ++ const tmpPath = tmpFile.get_path(); ++ ++ Command.run(fakeJasmine, ['--junit', tmpPath]); ++ expect(tmpFile.query_exists(null)).toBeTruthy(); ++ ++ tmpFile.delete_async(GLib.PRIORITY_DEFAULT, null) ++ .then(() => tmpFile.get_parent().delete_async(GLib.PRIORITY_DEFAULT, null)) ++ .then(() => tmpFile.get_parent().get_parent().delete_async(GLib.PRIORITY_DEFAULT, null)); ++ }); ++ ++ it('uses the value of JASMINE_JUNIT_REPORTS_DIR', function () { ++ const oldPath = GLib.getenv('JASMINE_JUNIT_REPORTS_DIR'); ++ const tmpDir = GLib.dir_make_tmp('junitreportXXXXXX'); ++ GLib.setenv('JASMINE_JUNIT_REPORTS_DIR', tmpDir, true); ++ ++ Command.run(fakeJasmine, ['--junit', 'report.xml']); ++ const reportFile = ++ Gio.File.new_for_path(tmpDir).get_child('report.xml'); ++ expect(reportFile.query_exists(null)).toBeTruthy(); ++ ++ reportFile.delete_async(GLib.PRIORITY_DEFAULT, null) ++ .then(() => reportFile.get_parent().delete_async(GLib.PRIORITY_DEFAULT, null)); ++ ++ if (oldPath !== null) ++ GLib.setenv('JASMINE_JUNIT_REPORTS_DIR', oldPath, true); ++ else ++ GLib.unsetenv('JASMINE_JUNIT_REPORTS_DIR'); ++ }); ++ ++ it('executes the Jasmine suite', function (done) { ++ expectAsync(Command.run(fakeJasmine, [])).toBeResolvedTo(0); ++ // fakeJasmine.execute() is started in idle ++ GLib.idle_add(GLib.PRIORITY_DEFAULT, function () { ++ expect(fakeJasmine.execute).toHaveBeenCalled(); ++ done(); ++ }); ++ }); ++ ++ it('runs the specified specs', function (done) { ++ Command.run(fakeJasmine, ['spec/some/fileSpec.js', '--no-color']); ++ GLib.idle_add(GLib.PRIORITY_DEFAULT, function () { ++ expect(fakeJasmine.execute).toHaveBeenCalledWith(['spec/some/fileSpec.js']); ++ done(); ++ }); ++ }); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/configSpec.js index 000000000,000000000..4edbf75a3 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/configSpec.js @@@ -1,0 -1,0 +1,270 @@@ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++import * as Config from '../src/config.js'; ++import * as Options from '../src/options.js'; ++ ++const [testFile] = GLib.filename_from_uri(import.meta.url); ++const testDir = GLib.path_get_dirname(testFile); ++ ++describe('Ensure array', function () { ++ it('does not change an array', function () { ++ expect(Config.ensureArray(['a', 'b'])).toEqual(['a', 'b']); ++ }); ++ ++ it('puts a single value into an array', function () { ++ expect(Config.ensureArray('a')).toEqual(['a']); ++ }); ++}); ++ ++describe('Loading configuration', function () { ++ beforeEach(function () { ++ // suppress messages ++ spyOn(globalThis, 'print'); ++ spyOn(globalThis, 'printerr'); ++ }); ++ ++ it('loads from a file', function () { ++ const config = Config.loadConfig({config: `${testDir}/fixtures/jasmine.json`}); ++ expect(config.a).toEqual('b'); ++ expect(config.c).toEqual('d'); ++ }); ++ ++ it("doesn't load the file if no-config specified", function () { ++ const config = Config.loadConfig({ ++ 'no-config': true, ++ config: `${testDir}/fixtures/jasmine.json`, ++ }); ++ const keys = Object.keys(config); ++ expect(keys).not.toContain('a'); ++ expect(keys).not.toContain('c'); ++ }); ++ ++ it('loads the default file if none given', function () { ++ const config = Config.loadConfig({}, `${testDir}/fixtures/jasmine.json`); ++ expect(config.a).toEqual('b'); ++ expect(config.c).toEqual('d'); ++ }); ++ ++ it("errors out if the file doesn't exist", function () { ++ expect(() => Config.loadConfig({config: 'nonexist.json'})).toThrow(); ++ }); ++ ++ it("doesn't error out if the default file doesn't exist", function () { ++ expect(() => Config.loadConfig({}, 'nonexist.json')).not.toThrow(); ++ }); ++ ++ it('errors out if the file is invalid', function () { ++ expect(() => Config.loadConfig({ ++ config: `${testDir}/fixtures/invalid.json`, ++ })).toThrow(); ++ }); ++ ++ it("resolves paths relative to the config file's location", function () { ++ const config = Config.loadConfig({config: `${testDir}/fixtures/path.json`}); ++ const location = Gio.File.new_for_path(`${testDir}/fixtures`); ++ ++ expect(config.include_paths).toContain(location.get_path()); ++ expect(config.spec_files).toContain(location.get_child('someSpec.js').get_path()); ++ }); ++ ++ it('warns about unrecognized config options', function () { ++ Config.loadConfig({config: `${testDir}/fixtures/jasmine.json`}); ++ expect(globalThis.printerr).toHaveBeenCalledWith(jasmine.stringMatching(/^warning: /)); ++ }); ++}); ++ ++describe('Configuration options to arguments', function () { ++ it('lets command line arguments override config options', function () { ++ const args = Config.configToArgs({options: '--color'}, ++ ...Options.parseOptions(['--no-color'])); ++ expect(args.indexOf('--no-color')).toBeGreaterThan(args.indexOf('--color')); ++ }); ++ ++ it('adds one exclusion path', function () { ++ const args = Config.configToArgs({exclude: 'a'}); ++ expect(args.join(' ')).toMatch('--exclude a'); ++ }); ++ ++ it('adds more than one exclusion path', function () { ++ const args = Config.configToArgs({exclude: ['a', 'b']}); ++ expect(args.join(' ')).toMatch('--exclude a'); ++ expect(args.join(' ')).toMatch('--exclude b'); ++ }); ++ ++ it('adds exclusions from the command line', function () { ++ const args = Config.configToArgs({}, ...Options.parseOptions(['--exclude', 'a.js'])); ++ expect(args.join(' ')).toMatch('--exclude a.js'); ++ }); ++ ++ it('combines exclusions from the command line and the config file', function () { ++ const args = Config.configToArgs({exclude: 'b.js'}, ++ ...Options.parseOptions(['--exclude', 'a.js'])); ++ expect(args.join(' ')).toMatch('--exclude a.js'); ++ expect(args.join(' ')).toMatch('--exclude b.js'); ++ }); ++ ++ it('adds one extra option', function () { ++ const args = Config.configToArgs({options: '--foo'}); ++ expect(args).toContain('--foo'); ++ }); ++ ++ it('adds more than one extra option', function () { ++ const args = Config.configToArgs({options: ['--foo', '--bar']}); ++ expect(args.join(' ')).toMatch('--foo --bar'); ++ // order should be preserved here ++ }); ++ ++ it('adds one spec file', function () { ++ const args = Config.configToArgs({spec_files: 'a'}); ++ expect(args).toContain('a'); ++ }); ++ ++ it('adds more than one spec file', function () { ++ const args = Config.configToArgs({spec_files: ['a', 'b']}); ++ expect(args).toContain('a'); ++ expect(args).toContain('b'); ++ }); ++ ++ it('does not add spec files from config if there were some on the command line', function () { ++ const args = Config.configToArgs({spec_files: ['a', 'b']}, ['c']); ++ expect(args).not.toContain('a'); ++ expect(args).not.toContain('b'); ++ }); ++ ++ it('passes the arguments on to the subprocess', function () { ++ const args = Config.configToArgs({}, ...Options.parseOptions(['--color', 'spec.js'])); ++ expect(args).toContain('--color', 'spec.js'); ++ }); ++ ++ it('passes the config file on to the subprocess as arguments', function () { ++ const args = Config.configToArgs({ ++ environment: {}, ++ options: ['--color'], ++ exclude: ['nonspec*.js'], ++ spec_files: ['a.js', 'b.js'], ++ }, [], {}); ++ expect(args.join(' ')).toMatch(/--exclude nonspec\*\.js/); ++ expect(args).toContain('--color', 'a.js', 'b.js'); ++ }); ++ ++ it('does not pass the config file specs if specs were on the command line', function () { ++ const args = Config.configToArgs({ ++ environment: {}, ++ spec_files: ['spec2.js'], ++ }, ['spec1.js']); ++ expect(args).toContain('spec1.js'); ++ expect(args).not.toContain('spec2.js'); ++ }); ++ ++ it('does not pass include paths as -I arguments', function () { ++ const args = Config.configToArgs({ ++ environment: {}, ++ include_paths: ['/path1', '/path2'], ++ }, [], {}); ++ expect(args.join(' ')).not.toMatch(/-I/); ++ }); ++}); ++ ++describe('Manipulating the environment', function () { ++ it('sets environment variables in the launcher', function () { ++ const launcher = Config.prepareLauncher({ ++ environment: { ++ 'MY_VARIABLE': 'my_value', ++ }, ++ }); ++ expect(launcher.getenv('MY_VARIABLE')).toEqual('my_value'); ++ }); ++ ++ it('unsets environment variables with null values', function () { ++ const launcher = Config.prepareLauncher({ ++ environment: { ++ 'MY_VARIABLE': null, ++ }, ++ }); ++ expect(launcher.getenv('MY_VARIABLE')).toBeNull(); ++ }); ++ ++ it('adds one search path', function () { ++ const launcher = Config.prepareLauncher({include_paths: '/a'}); ++ expect(launcher.getenv('GJS_PATH')).toEqual('/a'); ++ }); ++ ++ it('adds multiple search paths in the right order', function () { ++ const launcher = Config.prepareLauncher({include_paths: ['/a', '/b']}); ++ expect(launcher.getenv('GJS_PATH')).toEqual('/a:/b'); ++ }); ++ ++ it('adds search paths with a lower priority than existing search paths', function () { ++ const oldPath = GLib.getenv('GJS_PATH'); ++ GLib.setenv('GJS_PATH', '/a:/b', /* overwrite = */ true); ++ const launcher = Config.prepareLauncher({include_paths: ['/c', '/d']}); ++ expect(launcher.getenv('GJS_PATH')).toEqual('/a:/b:/c:/d'); ++ if (oldPath) ++ GLib.setenv('GJS_PATH', oldPath, /* overwrite = */ true); ++ else ++ GLib.unsetenv('GJS_PATH'); ++ }); ++}); ++ ++describe('Manipulating the launcher command line', function () { ++ let args; ++ ++ beforeEach(function () { ++ args = ['jasmine-runner', '--verbose', 'foo.js']; ++ }); ++ ++ it('executes jasmine-runner with a different interpreter binary', function () { ++ args = Config.wrapArgs(args, { ++ interpreter: '/path/to/custom/gjs', ++ }); ++ expect(args).toEqual(['/path/to/custom/gjs', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('allows adding arguments to the interpreter', function () { ++ args = Config.wrapArgs(args, { ++ interpreter: 'gjs -d', ++ }); ++ expect(args).toEqual(['gjs', '-d', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('executes jasmine-runner with a different interpreter binary from the command line', function () { ++ args = Config.wrapArgs(args, {}, { ++ interpreter: '/path/to/custom/gjs', ++ }); ++ expect(args).toEqual(['/path/to/custom/gjs', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('gives the interpreter specified on the command line priority', function () { ++ args = Config.wrapArgs(args, { ++ interpreter: '/path/to/other/gjs', ++ }, { ++ interpreter: '/path/to/custom/gjs', ++ }); ++ expect(args).toEqual(['/path/to/custom/gjs', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('executes jasmine-runner with a debugger', function () { ++ args = Config.wrapArgs(args, {}, { ++ debug: 'gdb --args', ++ }); ++ expect(args).toEqual(['gdb', '--args', 'gjs', '-m', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('does not pass the gjs interpreter to the debugger if a custom one is configured', function () { ++ args = Config.wrapArgs(args, { ++ interpreter: '/path/to/custom/gjs', ++ }, { ++ debug: 'lldb --', ++ }); ++ expect(args).toEqual(['lldb', '--', '/path/to/custom/gjs', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++ ++ it('does not pass the gjs interpreter to the debugger if a custom one is given on the command line', function () { ++ args = Config.wrapArgs(args, {}, { ++ debug: 'lldb --', ++ interpreter: '/path/to/custom/gjs', ++ }); ++ expect(args).toEqual(['lldb', '--', '/path/to/custom/gjs', 'jasmine-runner', '--verbose', 'foo.js']); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/consoleReporterSpec.js index 000000000,000000000..56a824f6f new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/consoleReporterSpec.js @@@ -1,0 -1,0 +1,118 @@@ ++import * as ConsoleReporter from '../src/consoleReporter.js'; ++ ++describe('Console reporter base class', function () { ++ let reporter, timerSpies; ++ const jasmineCorePath = 'path/to/jasmine/core/jasmine.js'; ++ ++ beforeEach(function () { ++ timerSpies = {}; ++ const timerSpy = id => { ++ timerSpies[id] = jasmine.createSpyObj('timer', ['start', 'elapsed']); ++ return timerSpies[id]; ++ }; ++ reporter = new ConsoleReporter.ConsoleReporter({ ++ timerFactory: timerSpy, ++ jasmineCorePath, ++ }); ++ }); ++ ++ it('can be instantiated', function () { ++ reporter = new ConsoleReporter.ConsoleReporter(); ++ }); ++ ++ it('starts the main timer when Jasmine starts', function () { ++ reporter.jasmineStarted(); ++ expect(timerSpies['main'].start).toHaveBeenCalled(); ++ }); ++ ++ it('purges Jasmine internals from stack traces', function () { ++ const fakeStack = [ ++ `foo${jasmineCorePath}`, ++ `bar ${jasmineCorePath}`, ++ 'line of useful stack trace', ++ `baz ${jasmineCorePath}`, ++ ].join('\n'); ++ const stackTrace = reporter.filterStack(fakeStack); ++ expect(stackTrace).toMatch('line of useful stack trace'); ++ expect(stackTrace).not.toMatch(jasmineCorePath); ++ }); ++ ++ describe('started signal', function () { ++ beforeEach(function () { ++ reporter = new ConsoleReporter.ConsoleReporter(); ++ }); ++ ++ it('is emitted when the suite starts', function (done) { ++ reporter.connect('started', () => done()); ++ reporter.jasmineStarted(); ++ }); ++ }); ++ ++ describe('complete signal', function () { ++ beforeEach(function () { ++ reporter = new ConsoleReporter.ConsoleReporter(); ++ reporter.jasmineStarted(); ++ }); ++ ++ it('is emitted with true when the suite is done', function (done) { ++ reporter.connect('complete', (_, success) => { ++ expect(success).toBeTruthy(); ++ done(); ++ }); ++ reporter.jasmineDone(); ++ }); ++ ++ it('is emitted with false if there are spec failures', function (done) { ++ reporter.connect('complete', (_, success) => { ++ expect(success).toBeFalsy(); ++ done(); ++ }); ++ reporter.specDone({status: 'failed', failedExpectations: []}); ++ reporter.jasmineDone(); ++ }); ++ ++ it('is emitted with false if there are suite failures', function (done) { ++ reporter.connect('complete', (_, success) => { ++ expect(success).toBeFalsy(); ++ done(); ++ }); ++ reporter.specDone({status: 'passed'}); ++ reporter.suiteDone({failedExpectations: [{message: 'bananas'}]}); ++ reporter.jasmineDone(); ++ }); ++ }); ++ ++ it('times individual suites', function () { ++ const suiteInfo = {id: 'foo'}; ++ reporter.suiteStarted(suiteInfo); ++ expect(timerSpies['suite:foo'].start).toHaveBeenCalled(); ++ ++ timerSpies['suite:foo'].elapsed.and.returnValue(800); ++ reporter.suiteDone(suiteInfo); ++ expect(suiteInfo.time).toBe(800); ++ }); ++ ++ it('times individual specs', function () { ++ const specInfo = { ++ id: 'foo', ++ status: 'passed', ++ }; ++ reporter.specStarted(specInfo); ++ expect(timerSpies['spec:foo'].start).toHaveBeenCalled(); ++ ++ timerSpies['spec:foo'].elapsed.and.returnValue(800); ++ reporter.specDone(specInfo); ++ expect(specInfo.time).toBe(800); ++ }); ++ ++ it('starts a timer', function () { ++ reporter.startTimer('foobar'); ++ expect(timerSpies['foobar'].start).toHaveBeenCalled(); ++ }); ++ ++ it('gets the elapsed time from a timer', function () { ++ reporter.startTimer('foobar'); ++ timerSpies['foobar'].elapsed.and.returnValue(500); ++ expect(reporter.elapsedTime('foobar')).toBe(500); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/defaultReporterSpec.js index 000000000,000000000..ca14fabf8 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/defaultReporterSpec.js @@@ -1,0 -1,0 +1,172 @@@ ++import * as ConsoleReporter from '../src/consoleReporter.js'; ++ ++describe('Default console reporter', function () { ++ let out, reporter, timerSpies; ++ ++ beforeEach(function () { ++ out = (function () { ++ let output = ''; ++ return { ++ print(str) { ++ output += str; ++ }, ++ getOutput() { ++ return output; ++ }, ++ clear() { ++ output = ''; ++ }, ++ }; ++ })(); ++ ++ timerSpies = {}; ++ const timerSpy = id => { ++ timerSpies[id] = jasmine.createSpyObj('timer', ['start', 'elapsed']); ++ return timerSpies[id]; ++ }; ++ ++ reporter = new ConsoleReporter.DefaultReporter({ ++ print: out.print, ++ show_colors: false, ++ timerFactory: timerSpy, ++ }); ++ }); ++ ++ it('reports that the suite has started to the console', function () { ++ reporter.jasmineStarted(); ++ expect(out.getOutput()).toEqual('Started\n'); ++ }); ++ ++ it('reports a passing spec as a dot', function () { ++ reporter.specDone({status: 'passed'}); ++ expect(out.getOutput()).toEqual('.'); ++ }); ++ ++ it('does not report a disabled spec', function () { ++ reporter.specDone({status: 'disabled'}); ++ expect(out.getOutput()).toEqual(''); ++ }); ++ ++ it('reports a failing spec as an "F"', function () { ++ reporter.specDone({status: 'failed'}); ++ expect(out.getOutput()).toEqual('F'); ++ }); ++ ++ it('reports a pending spec as a "*"', function () { ++ reporter.specDone({status: 'pending'}); ++ expect(out.getOutput()).toEqual('*'); ++ }); ++ ++ it('alerts user if there are no specs', function () { ++ reporter.jasmineStarted(); ++ out.clear(); ++ reporter.jasmineDone(); ++ expect(out.getOutput()).toMatch(/No specs found/); ++ }); ++ ++ it('reports a summary when done (singular spec)', function () { ++ reporter.jasmineStarted(); ++ reporter.specStarted({}); ++ reporter.specDone({status: 'passed'}); ++ ++ timerSpies['main'].elapsed.and.returnValue(1000); ++ ++ out.clear(); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1 spec, 0 failed/); ++ expect(out.getOutput()).not.toMatch(/0 pending/); ++ expect(out.getOutput()).toMatch('Finished in 1 s\n'); ++ }); ++ ++ it('reports a summary when done (pluralized specs)', function () { ++ reporter.jasmineStarted(); ++ reporter.specStarted({}); ++ reporter.specDone({status: 'passed'}); ++ reporter.specStarted({}); ++ reporter.specDone({status: 'pending'}); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ status: 'failed', ++ description: 'with a failing spec', ++ fullName: 'A suite with a failing spec', ++ failedExpectations: [{ ++ passed: false, ++ message: 'Expected true to be false.', ++ expected: false, ++ actual: true, ++ stack: 'fakeStack\nfakeStack', ++ }], ++ }); ++ ++ out.clear(); ++ ++ timerSpies['main'].elapsed.and.returnValue(100); ++ ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/3 specs, 1 failed, 1 pending/); ++ expect(out.getOutput()).toMatch('Finished in 0.1 s\n'); ++ }); ++ ++ it('reports a summary when done that includes the failed spec number before the full name of a failing spec', function () { ++ reporter.jasmineStarted(); ++ reporter.specDone({status: 'passed'}); ++ reporter.specDone({ ++ status: 'failed', ++ description: 'with a failing spec', ++ fullName: 'A suite with a failing spec', ++ failedExpectations: [{ ++ passed: false, ++ message: 'Expected true to be false.', ++ expected: false, ++ actual: true, ++ stack: 'fakeStack\nfakeStack', ++ }], ++ }); ++ ++ out.clear(); ++ ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1\) A suite with a failing spec/); ++ }); ++ ++ describe('with color', function () { ++ beforeEach(function () { ++ reporter = new ConsoleReporter.DefaultReporter({ ++ print: out.print, ++ showColors: true, ++ }); ++ }); ++ ++ it('reports that the suite has started to the console', function () { ++ reporter.jasmineStarted(); ++ expect(out.getOutput()).toEqual('Started\n'); ++ }); ++ ++ it('reports a passing spec as a dot', function () { ++ reporter.specDone({status: 'passed'}); ++ expect(out.getOutput()).toEqual('\x1B[32m.\x1B[0m'); ++ }); ++ ++ it('does not report a disabled spec', function () { ++ reporter.specDone({status: 'disabled'}); ++ expect(out.getOutput()).toEqual(''); ++ }); ++ ++ it('reports a failing spec as an "F"', function () { ++ reporter.specDone({status: 'failed'}); ++ expect(out.getOutput()).toEqual('\x1B[31mF\x1B[0m'); ++ }); ++ }); ++ ++ it('displays all afterAll exceptions', function () { ++ reporter.suiteDone({failedExpectations: [{message: 'After All Exception'}]}); ++ reporter.suiteDone({failedExpectations: [{message: 'Some Other Exception'}]}); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/After All Exception/); ++ expect(out.getOutput()).toMatch(/Some Other Exception/); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/fixtures/include.json index 000000000,000000000..f4c0ce09b new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/include.json @@@ -1,0 -1,0 +1,4 @@@ ++{ ++ "include_paths": "include", ++ "spec_files": "someSpec.js" ++} diff --cc subprojects/jasmine-gjs/test/fixtures/include/module.js index 000000000,000000000..4f4305c9e new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/include/module.js @@@ -1,0 -1,0 +1,5 @@@ ++/* exported importedFunction */ ++ ++function importedFunction() { ++ return true; ++} diff --cc subprojects/jasmine-gjs/test/fixtures/include/spec.js index 000000000,000000000..644ac6378 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/include/spec.js @@@ -1,0 -1,0 +1,5 @@@ ++describe('A spec that should not be loaded', function () { ++ it('is not loaded', function () { ++ fail('Spec was loaded when it should not be'); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/fixtures/invalid.json index 000000000,000000000..e69de29bb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/invalid.json diff --cc subprojects/jasmine-gjs/test/fixtures/jasmine.json index 000000000,000000000..88c6fe8c2 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/jasmine.json @@@ -1,0 -1,0 +1,4 @@@ ++{ ++ "a": "b", ++ "c": "d" ++} diff --cc subprojects/jasmine-gjs/test/fixtures/notASpec.txt index 000000000,000000000..e69de29bb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/notASpec.txt diff --cc subprojects/jasmine-gjs/test/fixtures/otherSpec.js index 000000000,000000000..e69de29bb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/otherSpec.js diff --cc subprojects/jasmine-gjs/test/fixtures/path.json index 000000000,000000000..fecccbb50 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/path.json @@@ -1,0 -1,0 +1,4 @@@ ++{ ++ "include_paths": ".", ++ "spec_files": "someSpec.js" ++} diff --cc subprojects/jasmine-gjs/test/fixtures/path1/test.js index 000000000,000000000..a680d88f0 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/path1/test.js @@@ -1,0 -1,0 +1,1 @@@ ++describe('A suite', function () {}); diff --cc subprojects/jasmine-gjs/test/fixtures/path2/test.js index 000000000,000000000..6fce0ddc7 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/path2/test.js @@@ -1,0 -1,0 +1,1 @@@ ++throw new Error('Catch this error to ensure this file is loaded'); diff --cc subprojects/jasmine-gjs/test/fixtures/someSpec.js index 000000000,000000000..e69de29bb new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/someSpec.js diff --cc subprojects/jasmine-gjs/test/fixtures/syntaxErrorSpec.js index 000000000,000000000..676e58ba3 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/fixtures/syntaxErrorSpec.js @@@ -1,0 -1,0 +1,2 @@@ ++lett foo = 4; ++describe('SyntaxError suite', function () {}); diff --cc subprojects/jasmine-gjs/test/focusedSpecIntegrationTest.js index 000000000,000000000..f860cf111 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/focusedSpecIntegrationTest.js @@@ -1,0 -1,0 +1,42 @@@ ++/* eslint no-restricted-globals: off */ ++ ++// This is a test of focused suites and specs with the fdescribe() and fit() ++// functions. It's taken from Jasmine's documentation suite: ++// http://jasmine.github.io/2.2/focused_specs.html ++ ++// By definition, this suite will disable all other suites that are run during ++// the same invocation of Jasmine -- so it is skipped by default. To run this ++// test anyway, run it explicitly with "jasmine ++// test/focusedSpecIntegrationTest.js". During "make check" it is still run, ++// since make runs the spec files one by one and so this suite won't interfere ++// with any other suites. ++ ++describe('Focused specs', function () { ++ fit('is focused and will run', function () { ++ expect(true).toBeTruthy(); ++ }); ++ ++ it('is not focused and will not run', function () { ++ expect(true).toBeFalsy(); ++ }); ++ ++ fdescribe('focused describe', function () { ++ it('will run', function () { ++ expect(true).toBeTruthy(); ++ }); ++ ++ it('will also run', function () { ++ expect(true).toBeTruthy(); ++ }); ++ }); ++ ++ fdescribe('another focused describe', function () { ++ fit('is focused and will run', function () { ++ expect(true).toBeTruthy(); ++ }); ++ ++ it('is not focused and will not run', function () { ++ expect(true).toBeFalsy(); ++ }); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/importerSpec.js index 000000000,000000000..f75fa65c6 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/importerSpec.js @@@ -1,0 -1,0 +1,11 @@@ ++const Utils = imports.utils; ++ ++describe('Jasmine importer', function () { ++ it('hides Jasmine modules from the test code', function () { ++ expect(Object.keys(Utils)).not.toContain('indenter'); ++ }); ++ ++ it("lets test code import modules named the same as Jasmine's", function () { ++ expect(Utils.add).toBeDefined(); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/jasmineBootSpec.js index 000000000,000000000..fd7de3c76 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/jasmineBootSpec.js @@@ -1,0 -1,0 +1,191 @@@ ++import Gio from 'gi://Gio'; ++import GLib from 'gi://GLib'; ++ ++import * as JasmineBoot from '../src/jasmineBoot.js'; ++ ++const [testFile] = GLib.filename_from_uri(import.meta.url); ++const testDir = GLib.path_get_dirname(testFile); ++ ++const customMatchers = { ++ toMatchAllFiles() { ++ return { ++ compare(actual, expected) { ++ const result = { ++ message: `Expected ${JSON.stringify(actual)} `, ++ }; ++ if (actual.length !== expected.length) { ++ result.pass = false; ++ result.message += `to match ${expected.length} ${ ++ expected.length === 1 ? 'file' : 'files' ++ }, but it contained ${actual.length}`; ++ return result; ++ } ++ ++ let unexpectedFile; ++ result.pass = actual.every(path => { ++ const actualFile = Gio.File.new_for_path(path); ++ const retval = expected.some(expectedPath => { ++ const expectedFile = Gio.File.new_for_path(expectedPath); ++ return actualFile.equal(expectedFile); ++ }); ++ if (!retval) ++ unexpectedFile = path; ++ return retval; ++ }); ++ if (result.pass) { ++ result.message += `not to match a list of files ${ ++ expected}, but it did.`; ++ } else if (unexpectedFile) { ++ result.message += `to match a list of files ${expected ++ }, but it contained ${unexpectedFile}`; ++ } else { ++ result.message += `to match the list of files ${expected ++ }, but it did not: ${actual}`; ++ } ++ return result; ++ }, ++ }; ++ }, ++}; ++ ++describe('Jasmine boot', function () { ++ let testJasmine; ++ ++ beforeEach(function () { ++ const bootedJasmine = { ++ getEnv: jasmine.createSpy('getEnv').and.returnValue({ ++ addReporter: jasmine.createSpy('addReporter'), ++ execute: jasmine.createSpy('execute'), ++ configure: jasmine.createSpy('configure'), ++ }), ++ Timer: jasmine.createSpy('Timer'), ++ Expectation: { ++ addMatchers: jasmine.createSpy('addMatchers'), ++ }, ++ }; ++ ++ const fakeJasmineRequireObj = { ++ core: jasmine.createSpy('core').and.returnValue(bootedJasmine), ++ interface: jasmine.createSpy('interface'), ++ }; ++ ++ const fakeJasmineCore = { ++ getJasmineRequireObj() { ++ return fakeJasmineRequireObj; ++ }, ++ __file__: 'fake/jasmine/path/jasmine.js', ++ }; ++ ++ testJasmine = new JasmineBoot.Jasmine({jasmineCore: fakeJasmineCore}); ++ ++ jasmine.addMatchers(customMatchers); ++ }); ++ ++ it('adds a nonexistent spec file', function () { ++ expect(testJasmine.specFiles).toEqual([]); ++ testJasmine.addSpecFiles([`${testDir}/non/existent/file.js`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/non/existent/file.js`, ++ ]); ++ }); ++ ++ it('adds a real spec file', function () { ++ expect(testJasmine.specFiles).toEqual([]); ++ testJasmine.addSpecFiles([`${testDir}/fixtures/someSpec.js`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/someSpec.js`, ++ ]); ++ }); ++ ++ it('adds more than one spec file', function () { ++ expect(testJasmine.specFiles).toEqual([]); ++ testJasmine.addSpecFiles([ ++ `${testDir}/fixtures/someSpec.js`, ++ `${testDir}/fixtures/otherSpec.js`, ++ ]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/someSpec.js`, ++ `${testDir}/fixtures/otherSpec.js`, ++ ]); ++ }); ++ ++ it('adds a whole directory of spec files', function () { ++ expect(testJasmine.specFiles).toEqual([]); ++ testJasmine.addSpecFiles([`${testDir}/fixtures`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/include/module.js`, ++ `${testDir}/fixtures/include/spec.js`, ++ `${testDir}/fixtures/otherSpec.js`, ++ `${testDir}/fixtures/path1/test.js`, ++ `${testDir}/fixtures/path2/test.js`, ++ `${testDir}/fixtures/someSpec.js`, ++ `${testDir}/fixtures/syntaxErrorSpec.js`, ++ ]); ++ expect(testJasmine.specFiles.every(path => path.indexOf('notASpec.txt') === -1)).toBe(true); ++ }); ++ ++ it('adds spec files in different directories with the same name', function () { ++ testJasmine.addSpecFiles([ ++ `${testDir}/fixtures/path1`, ++ `${testDir}/fixtures/path2`, ++ ]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/path1/test.js`, ++ `${testDir}/fixtures/path2/test.js`, ++ ]); ++ }); ++ ++ it('respects excluded files', function () { ++ testJasmine.exclusions = ['otherSpec.js', 'syntaxErrorSpec.js']; ++ testJasmine.addSpecFiles([`${testDir}/fixtures`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/include/module.js`, ++ `${testDir}/fixtures/include/spec.js`, ++ `${testDir}/fixtures/someSpec.js`, ++ `${testDir}/fixtures/path1/test.js`, ++ `${testDir}/fixtures/path2/test.js`, ++ ]); ++ }); ++ ++ it('matches at the end of the containing path', function () { ++ testJasmine.exclusions = ['test/fixtures']; ++ testJasmine.addSpecFiles([`${testDir}/fixtures`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([ ++ `${testDir}/fixtures/include/module.js`, ++ `${testDir}/fixtures/include/spec.js`, ++ `${testDir}/fixtures/path1/test.js`, ++ `${testDir}/fixtures/path2/test.js`, ++ ]); ++ }); ++ ++ it('can handle globs in excluded files', function () { ++ testJasmine.exclusions = ['*.js']; ++ testJasmine.addSpecFiles([`${testDir}/fixtures`]); ++ expect(testJasmine.specFiles).toMatchAllFiles([]); ++ }); ++ ++ it('adds the Jasmine path when adding a reporter', function () { ++ const fakeReporter = {}; ++ testJasmine.addReporter(fakeReporter); ++ expect(fakeReporter.jasmine_core_path).toMatch('fake/jasmine/path'); ++ }); ++ ++ it('imports spec files in different directories with the same name', function () { ++ testJasmine.addSpecFiles([ ++ `${testDir}/fixtures/path1`, ++ `${testDir}/fixtures/path2`, ++ ]); ++ expectAsync(testJasmine.loadSpecs()).toBeRejectedWithError(Error, ++ 'Catch this error to ensure this file is loaded'); ++ }); ++ ++ it('does not bail out altogether if one of the specs has a syntax error', function () { ++ testJasmine.addSpecFiles([`${testDir}/fixtures/syntaxErrorSpec.js`]); ++ expect(() => testJasmine.loadSpecs()).not.toThrow(); ++ }); ++ ++ it('does not bail out altogether if one of the specs does not exist', function () { ++ testJasmine.addSpecFiles(['non/existent/file.js']); ++ expect(() => testJasmine.loadSpecs()).not.toThrow(); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/jasmineIntegrationTest.js index 000000000,000000000..835ab4040 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/jasmineIntegrationTest.js @@@ -1,0 -1,0 +1,1012 @@@ ++// This suite is Jasmine's documentation suite, exercising all of Jasmine's ++// functionality to make sure that the GJS test runner has hooked everything up ++// correctly. It's taken from the following pages: ++// https://jasmine.github.io/2.3/introduction.html ++// https://jasmine.github.io/2.3/custom_equality.html ++// https://jasmine.github.io/2.3/custom_matcher.html ++// ++// Note: the "long asynchronous specs" suite near the bottom takes 9 seconds to ++// run. It is marked pending by default. To run this suite anyway, define an ++// environment variable RUN_THOROUGH_TESTS=yes. ++ ++/* global setInterval, setTimeout */ ++ ++import GLib from 'gi://GLib'; ++ ++describe('Jasmine integration test', function () { ++ describe("A suite", function () { ++ it("contains spec with an expectation", function () { ++ expect(true).toBe(true); ++ }); ++ }); ++ ++ describe("A suite is just a function", function () { ++ var a; ++ ++ it("and so is a spec", function () { ++ a = true; ++ ++ expect(a).toBe(true); ++ }); ++ }); ++ ++ describe("The 'toBe' matcher compares with ===", function () { ++ it("and has a positive case", function () { ++ expect(true).toBe(true); ++ }); ++ ++ it("and can have a negative case", function () { ++ expect(false).not.toBe(true); ++ }); ++ }); ++ ++ describe("Included matchers:", function () { ++ it("The 'toBe' matcher compares with ===", function () { ++ var a = 12; ++ var b = a; ++ ++ expect(a).toBe(b); ++ expect(a).not.toBe(null); ++ }); ++ ++ describe("The 'toEqual' matcher", function () { ++ it("works for simple literals and variables", function () { ++ var a = 12; ++ expect(a).toEqual(12); ++ }); ++ ++ it("should work for objects", function () { ++ var foo = { ++ a: 12, ++ b: 34 ++ }; ++ var bar = { ++ a: 12, ++ b: 34 ++ }; ++ expect(foo).toEqual(bar); ++ }); ++ }); ++ ++ it("The 'toMatch' matcher is for regular expressions", function () { ++ var message = "foo bar baz"; ++ ++ expect(message).toMatch(/bar/); ++ expect(message).toMatch("bar"); ++ expect(message).not.toMatch(/quux/); ++ }); ++ ++ it("The 'toBeDefined' matcher compares against `undefined`", function () { ++ var a = { ++ foo: "foo" ++ }; ++ ++ expect(a.foo).toBeDefined(); ++ expect(a.bar).not.toBeDefined(); ++ }); ++ ++ it("The `toBeUndefined` matcher compares against `undefined`", function () { ++ var a = { ++ foo: "foo" ++ }; ++ ++ expect(a.foo).not.toBeUndefined(); ++ expect(a.bar).toBeUndefined(); ++ }); ++ ++ it("The 'toBeNull' matcher compares against null", function () { ++ var a = null; ++ var foo = "foo"; ++ ++ expect(null).toBeNull(); ++ expect(a).toBeNull(); ++ expect(foo).not.toBeNull(); ++ }); ++ ++ it("The 'toBeTruthy' matcher is for boolean casting testing", function () { ++ var a, foo = "foo"; ++ ++ expect(foo).toBeTruthy(); ++ expect(a).not.toBeTruthy(); ++ }); ++ ++ it("The 'toBeFalsy' matcher is for boolean casting testing", function () { ++ var a, foo = "foo"; ++ ++ expect(a).toBeFalsy(); ++ expect(foo).not.toBeFalsy(); ++ }); ++ ++ describe("The 'toContain' matcher", function () { ++ it("works for finding an item in an Array", function () { ++ var a = ["foo", "bar", "baz"]; ++ ++ expect(a).toContain("bar"); ++ expect(a).not.toContain("quux"); ++ }); ++ ++ it("also works for finding a substring", function () { ++ var a = "foo bar baz"; ++ ++ expect(a).toContain("bar"); ++ expect(a).not.toContain("quux"); ++ }); ++ }); ++ ++ it("The 'toBeLessThan' matcher is for mathematical comparisons", function () { ++ var pi = 3.1415926, ++ e = 2.78; ++ ++ expect(e).toBeLessThan(pi); ++ expect(pi).not.toBeLessThan(e); ++ }); ++ ++ it("The 'toBeGreaterThan' matcher is for mathematical comparisons", function () { ++ var pi = 3.1415926, ++ e = 2.78; ++ ++ expect(pi).toBeGreaterThan(e); ++ expect(e).not.toBeGreaterThan(pi); ++ }); ++ ++ it("The 'toBeCloseTo' matcher is for precision math comparison", function () { ++ var pi = 3.1415926, ++ e = 2.78; ++ ++ expect(pi).not.toBeCloseTo(e, 2); ++ expect(pi).toBeCloseTo(e, 0); ++ }); ++ ++ it("The 'toThrow' matcher is for testing if a function throws an exception", function () { ++ var foo = function () { ++ return 1 + 2; ++ }; ++ var bar = function () { ++ return a + 1; ++ }; ++ var baz = function () { ++ throw 'what'; ++ }; ++ ++ expect(foo).not.toThrow(); ++ expect(bar).toThrow(); ++ expect(baz).toThrow('what'); ++ }); ++ ++ it("The 'toThrowError' matcher is for testing a specific thrown exception", function () { ++ var foo = function () { ++ throw new TypeError("foo bar baz"); ++ }; ++ ++ expect(foo).toThrowError("foo bar baz"); ++ expect(foo).toThrowError(/bar/); ++ expect(foo).toThrowError(TypeError); ++ expect(foo).toThrowError(TypeError, "foo bar baz"); ++ }); ++ }); ++ ++ describe("A spec using the fail function", function () { ++ var foo = function (x, callBack) { ++ if (x) { ++ callBack(); ++ } ++ }; ++ ++ it("should not call the callBack", function () { ++ foo(false, function () { ++ fail("Callback has been called"); ++ }); ++ }); ++ }); ++ ++ describe("A spec", function () { ++ it("is just a function, so it can contain any code", function () { ++ var foo = 0; ++ foo += 1; ++ ++ expect(foo).toEqual(1); ++ }); ++ ++ it("can have more than one expectation", function () { ++ var foo = 0; ++ foo += 1; ++ ++ expect(foo).toEqual(1); ++ expect(true).toEqual(true); ++ }); ++ }); ++ ++ describe("A spec using beforeEach and afterEach", function () { ++ var foo = 0; ++ ++ beforeEach(function () { ++ foo += 1; ++ }); ++ ++ afterEach(function () { ++ foo = 0; ++ }); ++ ++ it("is just a function, so it can contain any code", function () { ++ expect(foo).toEqual(1); ++ }); ++ ++ it("can have more than one expectation", function () { ++ expect(foo).toEqual(1); ++ expect(true).toEqual(true); ++ }); ++ }); ++ ++ describe("A spec using beforeAll and afterAll", function () { ++ var foo; ++ ++ beforeAll(function () { ++ foo = 1; ++ }); ++ ++ afterAll(function () { ++ foo = 0; ++ }); ++ ++ it("sets the initial value of foo before specs run", function () { ++ expect(foo).toEqual(1); ++ foo += 1; ++ }); ++ ++ it("does not reset foo between specs", function () { ++ expect(foo).toEqual(2); ++ }); ++ }); ++ ++ describe("A spec", function () { ++ beforeEach(function () { ++ this.foo = 0; ++ }); ++ ++ it("can use the `this` to share state", function () { ++ expect(this.foo).toEqual(0); ++ this.bar = "test pollution?"; ++ }); ++ ++ it("prevents test pollution by having an empty `this` created for the next spec", function () { ++ expect(this.foo).toEqual(0); ++ expect(this.bar).toBe(undefined); ++ }); ++ }); ++ ++ describe("A spec", function () { ++ var foo; ++ ++ beforeEach(function () { ++ foo = 0; ++ foo += 1; ++ }); ++ ++ afterEach(function () { ++ foo = 0; ++ }); ++ ++ it("is just a function, so it can contain any code", function () { ++ expect(foo).toEqual(1); ++ }); ++ ++ it("can have more than one expectation", function () { ++ expect(foo).toEqual(1); ++ expect(true).toEqual(true); ++ }); ++ ++ describe("nested inside a second describe", function () { ++ var bar; ++ ++ beforeEach(function () { ++ bar = 1; ++ }); ++ ++ it("can reference both scopes as needed", function () { ++ expect(foo).toEqual(bar); ++ }); ++ }); ++ }); ++ ++ xdescribe("A spec", function () { ++ var foo; ++ ++ beforeEach(function () { ++ foo = 0; ++ foo += 1; ++ }); ++ ++ it("is just a function, so it can contain any code", function () { ++ expect(foo).toEqual(1); ++ }); ++ }); ++ ++ describe("Pending specs", function () { ++ xit("can be declared 'xit'", function () { ++ expect(true).toBe(false); ++ }); ++ ++ it("can be declared with 'it' but without a function"); ++ ++ it("can be declared by calling 'pending' in the spec body", function () { ++ expect(true).toBe(false); ++ pending('this is why it is pending'); ++ }); ++ }); ++ ++ describe("A spy", function () { ++ var foo, bar = null; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ } ++ }; ++ ++ spyOn(foo, 'setBar'); ++ ++ foo.setBar(123); ++ foo.setBar(456, 'another param'); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ expect(foo.setBar).toHaveBeenCalled(); ++ }); ++ ++ it("tracks that the spy was called x times", function () { ++ expect(foo.setBar).toHaveBeenCalledTimes(2); ++ }); ++ ++ it("tracks all the arguments of its calls", function () { ++ expect(foo.setBar).toHaveBeenCalledWith(123); ++ expect(foo.setBar).toHaveBeenCalledWith(456, 'another param'); ++ }); ++ ++ it("stops all execution on a function", function () { ++ expect(bar).toBeNull(); ++ }); ++ }); ++ ++ describe("A spy, when configured to call through", function () { ++ var foo, bar, fetchedBar; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ }, ++ getBar: function () { ++ return bar; ++ } ++ }; ++ ++ spyOn(foo, 'getBar').and.callThrough(); ++ ++ foo.setBar(123); ++ fetchedBar = foo.getBar(); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ expect(foo.getBar).toHaveBeenCalled(); ++ }); ++ ++ it("should not affect other functions", function () { ++ expect(bar).toEqual(123); ++ }); ++ ++ it("when called returns the requested value", function () { ++ expect(fetchedBar).toEqual(123); ++ }); ++ }); ++ ++ describe("A spy, when configured to fake a return value", function () { ++ var foo, bar, fetchedBar; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ }, ++ getBar: function () { ++ return bar; ++ } ++ }; ++ ++ spyOn(foo, "getBar").and.returnValue(745); ++ ++ foo.setBar(123); ++ fetchedBar = foo.getBar(); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ expect(foo.getBar).toHaveBeenCalled(); ++ }); ++ ++ it("should not affect other functions", function () { ++ expect(bar).toEqual(123); ++ }); ++ ++ it("when called returns the requested value", function () { ++ expect(fetchedBar).toEqual(745); ++ }); ++ }); ++ ++ describe("A spy, when configured to fake a series of return values", function () { ++ var foo, bar; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function(value) { ++ bar = value; ++ }, ++ getBar: function () { ++ return bar; ++ } ++ }; ++ ++ spyOn(foo, "getBar").and.returnValues("fetched first", "fetched second"); ++ ++ foo.setBar(123); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ foo.getBar(123); ++ expect(foo.getBar).toHaveBeenCalled(); ++ }); ++ ++ it("should not affect other functions", function () { ++ expect(bar).toEqual(123); ++ }); ++ ++ it("when called multiple times returns the requested values in order", function () { ++ expect(foo.getBar()).toEqual("fetched first"); ++ expect(foo.getBar()).toEqual("fetched second"); ++ expect(foo.getBar()).toBeUndefined(); ++ }); ++ }); ++ ++ describe("A spy, when configured with an alternate implementation", function () { ++ var foo, bar, fetchedBar; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ }, ++ getBar: function () { ++ return bar; ++ } ++ }; ++ ++ spyOn(foo, "getBar").and.callFake(function (args, can, be, received) { ++ return 1001; ++ }); ++ ++ foo.setBar(123); ++ fetchedBar = foo.getBar(); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ expect(foo.getBar).toHaveBeenCalled(); ++ }); ++ ++ it("should not affect other functions", function () { ++ expect(bar).toEqual(123); ++ }); ++ ++ it("when called returns the requested value", function () { ++ expect(fetchedBar).toEqual(1001); ++ }); ++ }); ++ ++ describe("A spy, when configured to throw an error", function () { ++ var foo, bar; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ } ++ }; ++ ++ spyOn(foo, "setBar").and.throwError("quux"); ++ }); ++ ++ it("throws the value", function () { ++ expect(function () { ++ foo.setBar(123); ++ }).toThrowError("quux"); ++ }); ++ }); ++ ++ describe("A spy", function () { ++ var foo, bar = null; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ } ++ }; ++ ++ spyOn(foo, 'setBar').and.callThrough(); ++ }); ++ ++ it("can call through and then stub in the same spec", function () { ++ foo.setBar(123); ++ expect(bar).toEqual(123); ++ ++ foo.setBar.and.stub(); ++ bar = null; ++ ++ foo.setBar(123); ++ expect(bar).toBe(null); ++ }); ++ }); ++ ++ describe("A spy", function () { ++ var foo, bar = null; ++ ++ beforeEach(function () { ++ foo = { ++ setBar: function (value) { ++ bar = value; ++ } ++ }; ++ ++ spyOn(foo, 'setBar'); ++ }); ++ ++ it("tracks if it was called at all", function () { ++ expect(foo.setBar.calls.any()).toEqual(false); ++ ++ foo.setBar(); ++ ++ expect(foo.setBar.calls.any()).toEqual(true); ++ }); ++ ++ it("tracks the number of times it was called", function () { ++ expect(foo.setBar.calls.count()).toEqual(0); ++ ++ foo.setBar(); ++ foo.setBar(); ++ ++ expect(foo.setBar.calls.count()).toEqual(2); ++ }); ++ ++ it("tracks the arguments of each call", function () { ++ foo.setBar(123); ++ foo.setBar(456, "baz"); ++ ++ expect(foo.setBar.calls.argsFor(0)).toEqual([123]); ++ expect(foo.setBar.calls.argsFor(1)).toEqual([456, "baz"]); ++ }); ++ ++ it("tracks the arguments of all calls", function () { ++ foo.setBar(123); ++ foo.setBar(456, "baz"); ++ ++ expect(foo.setBar.calls.allArgs()).toEqual([[123],[456, "baz"]]); ++ }); ++ ++ it("can provide the context and arguments to all calls", function () { ++ foo.setBar(123); ++ ++ expect(foo.setBar.calls.all()).toEqual([jasmine.objectContaining({object: foo, args: [123], returnValue: undefined})]); ++ }); ++ ++ it("has a shortcut to the most recent call", function () { ++ foo.setBar(123); ++ foo.setBar(456, "baz"); ++ ++ expect(foo.setBar.calls.mostRecent()).toEqual(jasmine.objectContaining({object: foo, args: [456, "baz"], returnValue: undefined})); ++ }); ++ ++ it("has a shortcut to the first call", function () { ++ foo.setBar(123); ++ foo.setBar(456, "baz"); ++ ++ expect(foo.setBar.calls.first()).toEqual(jasmine.objectContaining({object: foo, args: [123], returnValue: undefined})); ++ }); ++ ++ it("tracks the context", function () { ++ var spy = jasmine.createSpy('spy'); ++ var baz = { ++ fn: spy ++ }; ++ var quux = { ++ fn: spy ++ }; ++ baz.fn(123); ++ quux.fn(456); ++ ++ expect(spy.calls.first().object).toBe(baz); ++ expect(spy.calls.mostRecent().object).toBe(quux); ++ }); ++ ++ it("can be reset", function () { ++ foo.setBar(123); ++ foo.setBar(456, "baz"); ++ ++ expect(foo.setBar.calls.any()).toBe(true); ++ ++ foo.setBar.calls.reset(); ++ ++ expect(foo.setBar.calls.any()).toBe(false); ++ }); ++ }); ++ ++ describe("A spy, when created manually", function () { ++ var whatAmI; ++ ++ beforeEach(function () { ++ whatAmI = jasmine.createSpy('whatAmI'); ++ ++ whatAmI("I", "am", "a", "spy"); ++ }); ++ ++ it("is named, which helps in error reporting", function () { ++ expect(whatAmI.and.identity).toEqual('whatAmI'); ++ }); ++ ++ it("tracks that the spy was called", function () { ++ expect(whatAmI).toHaveBeenCalled(); ++ }); ++ ++ it("tracks its number of calls", function () { ++ expect(whatAmI.calls.count()).toEqual(1); ++ }); ++ ++ it("tracks all the arguments of its calls", function () { ++ expect(whatAmI).toHaveBeenCalledWith("I", "am", "a", "spy"); ++ }); ++ ++ it("allows access to the most recent call", function () { ++ expect(whatAmI.calls.mostRecent().args[0]).toEqual("I"); ++ }); ++ }); ++ ++ describe("Multiple spies, when created manually", function () { ++ var tape; ++ ++ beforeEach(function () { ++ tape = jasmine.createSpyObj('tape', ['play', 'pause', 'stop', 'rewind']); ++ ++ tape.play(); ++ tape.pause(); ++ tape.rewind(0); ++ }); ++ ++ it("creates spies for each requested function", function () { ++ expect(tape.play).toBeDefined(); ++ expect(tape.pause).toBeDefined(); ++ expect(tape.stop).toBeDefined(); ++ expect(tape.rewind).toBeDefined(); ++ }); ++ ++ it("tracks that the spies were called", function () { ++ expect(tape.play).toHaveBeenCalled(); ++ expect(tape.pause).toHaveBeenCalled(); ++ expect(tape.rewind).toHaveBeenCalled(); ++ expect(tape.stop).not.toHaveBeenCalled(); ++ }); ++ ++ it("tracks all the arguments of its calls", function () { ++ expect(tape.rewind).toHaveBeenCalledWith(0); ++ }); ++ }); ++ ++ describe("jasmine.any", function () { ++ it("matches any value", function () { ++ expect({}).toEqual(jasmine.any(Object)); ++ expect(12).toEqual(jasmine.any(Number)); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful for comparing arguments", function () { ++ var foo = jasmine.createSpy('foo'); ++ foo(12, function () { ++ return true; ++ }); ++ ++ expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function)); ++ }); ++ }); ++ }); ++ ++ describe("jasmine.anything", function () { ++ it("matches anything", function () { ++ expect(1).toEqual(jasmine.anything()); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful when the argument can be ignored", function () { ++ var foo = jasmine.createSpy('foo'); ++ foo(12, function () { ++ return false; ++ }); ++ ++ expect(foo).toHaveBeenCalledWith(12, jasmine.anything()); ++ }); ++ }); ++ }); ++ ++ describe("jasmine.objectContaining", function () { ++ var foo; ++ ++ beforeEach(function () { ++ foo = { ++ a: 1, ++ b: 2, ++ bar: "baz" ++ }; ++ }); ++ ++ it("matches objects with the expect key/value pairs", function () { ++ expect(foo).toEqual(jasmine.objectContaining({ ++ bar: "baz" ++ })); ++ expect(foo).not.toEqual(jasmine.objectContaining({ ++ c: 37 ++ })); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful for comparing arguments", function () { ++ var callback = jasmine.createSpy('callback'); ++ ++ callback({ ++ bar: "baz" ++ }); ++ ++ expect(callback).toHaveBeenCalledWith(jasmine.objectContaining({ ++ bar: "baz" ++ })); ++ expect(callback).not.toHaveBeenCalledWith(jasmine.objectContaining({ ++ c: 37 ++ })); ++ }); ++ }); ++ }); ++ ++ describe("jasmine.arrayContaining", function () { ++ var foo; ++ ++ beforeEach(function () { ++ foo = [1, 2, 3, 4]; ++ }); ++ ++ it("matches arrays with some of the values", function () { ++ expect(foo).toEqual(jasmine.arrayContaining([3, 1])); ++ expect(foo).not.toEqual(jasmine.arrayContaining([6])); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful when comparing arguments", function () { ++ var callback = jasmine.createSpy('callback'); ++ ++ callback([1, 2, 3, 4]); ++ ++ expect(callback).toHaveBeenCalledWith(jasmine.arrayContaining([4, 2, 3])); ++ expect(callback).not.toHaveBeenCalledWith(jasmine.arrayContaining([5, 2])); ++ }); ++ }); ++ }); ++ ++ describe('jasmine.stringMatching', function () { ++ it("matches as a regexp", function () { ++ expect({foo: 'bar'}).toEqual({foo: jasmine.stringMatching(/^bar$/)}); ++ expect({foo: 'foobarbaz'}).toEqual({foo: jasmine.stringMatching('bar')}); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful for comparing arguments", function () { ++ var callback = jasmine.createSpy('callback'); ++ ++ callback('foobarbaz'); ++ ++ expect(callback).toHaveBeenCalledWith(jasmine.stringMatching('bar')); ++ expect(callback).not.toHaveBeenCalledWith(jasmine.stringMatching(/^bar$/)); ++ }); ++ }); ++ }); ++ ++ describe("custom asymmetry", function () { ++ var tester = { ++ asymmetricMatch: function (actual) { ++ var secondValue = actual.split(',')[1]; ++ return secondValue === 'bar'; ++ } ++ }; ++ ++ it("dives in deep", function () { ++ expect("foo,bar,baz,quux").toEqual(tester); ++ }); ++ ++ describe("when used with a spy", function () { ++ it("is useful for comparing arguments", function () { ++ var callback = jasmine.createSpy('callback'); ++ ++ callback('foo,bar,baz'); ++ ++ expect(callback).toHaveBeenCalledWith(tester); ++ }); ++ }); ++ }); ++ ++ describe("Manually ticking the Jasmine Clock", function () { ++ var timerCallback; ++ ++ beforeEach(function () { ++ timerCallback = jasmine.createSpy("timerCallback"); ++ jasmine.clock().install(); ++ }); ++ ++ afterEach(function () { ++ jasmine.clock().uninstall(); ++ }); ++ ++ it("causes a timeout to be called synchronously", function () { ++ setTimeout(function () { ++ timerCallback(); ++ }, 100); ++ ++ expect(timerCallback).not.toHaveBeenCalled(); ++ ++ jasmine.clock().tick(101); ++ ++ expect(timerCallback).toHaveBeenCalled(); ++ }); ++ ++ it("causes an interval to be called synchronously", function () { ++ setInterval(function () { ++ timerCallback(); ++ }, 100); ++ ++ expect(timerCallback).not.toHaveBeenCalled(); ++ ++ jasmine.clock().tick(101); ++ expect(timerCallback.calls.count()).toEqual(1); ++ ++ jasmine.clock().tick(50); ++ expect(timerCallback.calls.count()).toEqual(1); ++ ++ jasmine.clock().tick(50); ++ expect(timerCallback.calls.count()).toEqual(2); ++ }); ++ ++ describe("Mocking the Date object", function () { ++ it("mocks the Date object and sets it to a given time", function () { ++ var baseTime = new Date(2013, 9, 23); ++ // If you do not provide a base time to `mockDate` it will use the current date. ++ jasmine.clock().mockDate(baseTime); ++ ++ jasmine.clock().tick(50); ++ expect(new Date().getTime()).toEqual(baseTime.getTime() + 50); ++ }); ++ }); ++ }); ++ ++ describe("Asynchronous specs", function () { ++ var value; ++ ++ beforeEach(function (done) { ++ setTimeout(function () { ++ value = 0; ++ done(); ++ }, 1); ++ }); ++ ++ it("should support async execution of test preparation and expectations", function (done) { ++ value++; ++ expect(value).toBeGreaterThan(0); ++ done(); ++ }); ++ ++ describe("long asynchronous specs", function () { ++ beforeEach(function (done) { ++ done(); ++ }, 1000); ++ ++ if (GLib.getenv('RUN_THOROUGH_TESTS') === 'yes') { ++ it("takes a long time", function (done) { ++ setTimeout(function () { ++ done(); ++ }, 9000); ++ }, 10000); ++ } ++ ++ afterEach(function (done) { ++ done(); ++ }, 1000); ++ }); ++ ++ describe("A spec using done.fail", function() { ++ var foo = function(x, callBack1, callBack2) { ++ if (x) { ++ setTimeout(callBack1, 0); ++ } else { ++ setTimeout(callBack2, 0); ++ } ++ }; ++ ++ it("should not call the second callBack", function(done) { ++ foo(true, ++ done, ++ function() { ++ done.fail("Second callback has been called"); ++ } ++ ); ++ }); ++ }); ++ }); ++ ++ describe("custom equality", function () { ++ var myCustomEquality = function (first, second) { ++ if (typeof first == "string" && typeof second == "string") { ++ return first[0] == second[1]; ++ } ++ }; ++ ++ beforeEach(function () { ++ jasmine.addCustomEqualityTester(myCustomEquality); ++ }); ++ ++ it("should be custom equal", function () { ++ expect("abc").toEqual("aaa"); ++ }); ++ ++ it("should be custom not equal", function () { ++ expect("abc").not.toEqual("abc"); ++ }); ++ }); ++ ++ var customMatchers = { ++ toBeGoofy: function (util, customEqualityTesters) { ++ return { ++ compare: function (actual, expected) { ++ if (expected === undefined) { ++ expected = ''; ++ } ++ ++ var result = {}; ++ ++ result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters); ++ ++ if (result.pass) { ++ result.message = "Expected " + actual + " not to be quite so goofy"; ++ } else { ++ result.message = "Expected " + actual + " to be goofy, but it was not very goofy"; ++ } ++ ++ return result; ++ } ++ }; ++ } ++ }; ++ ++ describe("Custom matcher: 'toBeGoofy'", function () { ++ beforeEach(function () { ++ jasmine.addMatchers(customMatchers); ++ }); ++ ++ it("is available on an expectation", function () { ++ expect({ ++ hyuk: 'gawrsh' ++ }).toBeGoofy(); ++ }); ++ ++ it("can take an 'expected' parameter", function () { ++ expect({ ++ hyuk: 'gawrsh is fun' ++ }).toBeGoofy(' is fun'); ++ }); ++ ++ it("can be negated", function () { ++ expect({ ++ hyuk: 'this is fun' ++ }).not.toBeGoofy(); ++ }); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/junitReporterSpec.js index 000000000,000000000..6c4061eaa new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/junitReporterSpec.js @@@ -1,0 -1,0 +1,470 @@@ ++import GLib from 'gi://GLib'; ++ ++import * as JUnitReporter from '../src/junitReporter.js'; ++import * as XMLWriter from '../src/xmlWriter.js'; ++ ++const SUITE_INFO = { ++ id: 'foo', ++ description: 'A suite', ++ fullName: 'A suite', ++ failedExpectations: [], ++ status: 'finished', ++}; ++const NESTED_SUITE_INFO = { ++ id: 'baz', ++ description: 'nested', ++ fullName: 'A suite nested', ++ failedExpectations: [], ++ status: 'finished', ++}; ++const FAILED_SUITE_INFO = { ++ id: 'cheers', ++ description: 'A failing suite', ++ fullName: 'A failing suite', ++ failedExpectations: [{ ++ matcherName: '', ++ message: 'Some error', ++ stack: 'file.js:113\nfile.js:72\nfile.js:17\n', ++ }], ++ status: 'failed', ++}; ++const PASSING_SPEC_INFO = { ++ id: 'bar', ++ description: 'passes a test', ++ fullName: 'A suite passes a test', ++ failedExpectations: [], ++ passedExpectations: [ ++ { ++ matcherName: 'toBe', ++ message: 'Expected true to be true', ++ }, ++ { ++ matcherName: 'toContain', ++ message: 'Expected [1] to contain 1', ++ }, ++ ], ++ status: 'passed', ++}; ++const NESTED_PASSING_SPEC_INFO = { ++ id: 'boz', ++ description: 'passes a test', ++ fullName: 'A suite nested passes a test', ++ failedExpectations: [], ++ passedExpectations: [], ++ status: 'passed', ++}; ++const PENDING_SPEC_INFO = { ++ id: 'skip', ++ description: 'skips a test', ++ fullName: 'A suite skips a test', ++ failedExpectations: [], ++ passedExpectations: [], ++ status: 'pending', ++}; ++const FAILING_SPEC_INFO = { ++ id: 'bad', ++ description: 'fails a test', ++ fullName: 'A suite fails a test', ++ failedExpectations: [{ ++ matcherName: 'toBe', ++ message: 'Expected true to be false', ++ stack: 'file.js:113\nfile.js:72\nfile.js:17\n', ++ }], ++ passedExpectations: [], ++ status: 'failed', ++}; ++const ERROR_SPEC_INFO = { ++ id: 'bug', ++ description: 'has a bug in a test', ++ fullName: 'A suite has a bug in a test', ++ failedExpectations: [ ++ { ++ matcherName: '', ++ message: 'TypeError: foo is not a function', ++ stack: 'file.js:113\nfile.js:72\nfile.js:17\n', ++ }, ++ { ++ matcherName: '', ++ message: 'Some other unknown error', ++ stack: 'file.js:113\nfile.js:72\nfile.js:17\n', ++ }, ++ ], ++ passedExpectations: [], ++ status: 'failed', ++}; ++const DISABLED_SPEC_INFO = { ++ id: 'wut', ++ description: 'disables a test', ++ fullName: 'A suite disables a test', ++ failedExpectations: [], ++ passedExpectations: [], ++ status: 'disabled', ++}; ++ ++describe('The JUnit reporter', function () { ++ let out, reporter, timerSpies; ++ ++ beforeEach(function () { ++ // Override the XML outputting function to output JSON instead. This is ++ // for ease of verifying the output. XML is inconvenient to parse in the ++ // DOM-less GJS. Any regressions in the XML output should not be tested ++ // here, but instead should be covered in xmlWriterSpec.js. ++ spyOn(XMLWriter.Node.prototype, 'toString').and.callFake(function () { ++ return JSON.stringify(this); ++ }); ++ ++ out = (function () { ++ let output = ''; ++ return { ++ print(str) { ++ output += str; ++ }, ++ getOutput() { ++ return output; ++ }, ++ clear() { ++ output = ''; ++ }, ++ }; ++ })(); ++ ++ timerSpies = {}; ++ const timerSpy = id => { ++ timerSpies[id] = jasmine.createSpyObj('timer', ['start', 'elapsed']); ++ return timerSpies[id]; ++ }; ++ ++ reporter = new JUnitReporter.JUnitReporter({ ++ print: out.print, ++ timerFactory: timerSpy, ++ }); ++ reporter.jasmineStarted(); ++ }); ++ ++ function runSpec(specInfo) { ++ reporter.specStarted(specInfo); ++ reporter.specDone(specInfo); ++ } ++ ++ function runSuite(suiteInfo, specs) { ++ reporter.suiteStarted(suiteInfo); ++ specs.forEach(runSpec); ++ reporter.suiteDone(suiteInfo); ++ } ++ ++ // Find the element with the given ID inside the ++ // element given by tree. This is necessary because other elements may be ++ // present such as, , so we cannot rely on the element with ID 0 ++ // being the first child of . ++ function findSuite(tree, id) { ++ for (let index = 0; index < tree.children.length; index++) { ++ const child = tree.children[index]; ++ if (child.name === 'testsuite' && child.attrs['id'] === id) ++ return child; ++ } ++ return undefined; ++ } ++ ++ // For XML builder reasons, the report is only output at the end of all the ++ // test suites. Therefore all tests must call jasmineDone(). ++ ++ it('outputs a JUnit report', function () { ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ expect(tree.name).toBe('testsuites'); ++ }); ++ ++ it('reports all required elements of a test suite', function () { ++ runSuite(SUITE_INFO, []); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.name).toBe('testsuite'); ++ expect(testsuite.attrs['name']).toBe('A suite'); ++ expect(testsuite.attrs['tests']).toBe(0); ++ }); ++ ++ it('reports all required elements of a test case element', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ const [{name, attrs}] = testsuite.children; ++ expect(name).toBe('testcase'); ++ expect(attrs['name']).toBe('passes a test'); ++ expect(attrs['classname']).toBe('A suite'); ++ }); ++ ++ it('reports a pending spec as skipped', function () { ++ runSuite(SUITE_INFO, [PENDING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ const [{children}] = testsuite.children; ++ expect(children[0].name).toBe('skipped'); ++ }); ++ ++ describe('given a spec with a failed expectation', function () { ++ let failure; ++ ++ beforeEach(function () { ++ runSuite(SUITE_INFO, [FAILING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ [failure] = testsuite.children[0].children; ++ }); ++ ++ it('reports it as failed', function () { ++ expect(failure.name).toBe('failure'); ++ }); ++ ++ it('reports the matcher name as the failure type', function () { ++ if (!failure.attrs.hasOwnProperty('type')) ++ pending(); ++ expect(failure.attrs['type']).toBe('toBe'); ++ }); ++ ++ it('reports the expectation message', function () { ++ if (!failure.attrs.hasOwnProperty('message')) ++ pending(); ++ expect(failure.attrs['message']).toBe('Expected true to be false'); ++ }); ++ ++ it('reports the stack trace', function () { ++ expect(failure.text).toBe('file.js:113\nfile.js:72\nfile.js:17\n'); ++ }); ++ }); ++ ++ describe('given a spec with an uncaught exception', function () { ++ let error1, error2; ++ ++ beforeEach(function () { ++ runSuite(SUITE_INFO, [ERROR_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ [error1, error2] = testsuite.children[0].children; ++ }); ++ ++ it('reports it as errored', function () { ++ expect(error1.name).toBe('error'); ++ expect(error2.name).toBe('error'); ++ }); ++ ++ it('reports the exception class as the failure type', function () { ++ expect(error1.attrs['type']).toBe('TypeError'); ++ }); ++ ++ it('picks a default type if the exception class is not known', function () { ++ expect(error2.attrs['type']).toBe('Error'); ++ }); ++ ++ it('reports the error message', function () { ++ expect(error1.attrs['message']).toBe('TypeError: foo is not a function'); ++ expect(error2.attrs['message']).toBe('Some other unknown error'); ++ }); ++ ++ it('reports the stack trace', function () { ++ expect(error1.text).toBe('file.js:113\nfile.js:72\nfile.js:17\n'); ++ expect(error2.text).toBe('file.js:113\nfile.js:72\nfile.js:17\n'); ++ }); ++ }); ++ ++ it('does not report a disabled spec', function () { ++ runSuite(SUITE_INFO, [DISABLED_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.children.length).toBe(0); ++ }); ++ ++ it('gives each suite an increasing ID number', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO]); ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO]); ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ tree.children.filter(child => child.name === 'testsuite') ++ .forEach((child, index) => { ++ expect(child.attrs['id']).toBe(index); ++ }); ++ }); ++ ++ it('times all suites together', function () { ++ timerSpies['main'].elapsed.and.returnValue(1200); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ expect(tree.attrs['time']).toBeCloseTo(1.2, 4); ++ }); ++ ++ it('times individual suites', function () { ++ reporter.suiteStarted(SUITE_INFO); ++ timerSpies[`suite:${SUITE_INFO.id}`].elapsed.and.returnValue(100); ++ reporter.suiteDone(SUITE_INFO); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['time']).toBeCloseTo(0.1, 4); ++ }); ++ ++ it('times individual specs', function () { ++ reporter.suiteStarted(SUITE_INFO); ++ reporter.specStarted(PASSING_SPEC_INFO); ++ timerSpies[`spec:${PASSING_SPEC_INFO.id}`].elapsed.and.returnValue(100); ++ reporter.specDone(PASSING_SPEC_INFO); ++ reporter.suiteDone(SUITE_INFO); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ const [{attrs}] = testsuite.children; ++ expect(attrs['time']).toBeCloseTo(0.1, 4); ++ }); ++ ++ it('counts all tests in a suite', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, PASSING_SPEC_INFO, PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['tests']).toBe(3); ++ }); ++ ++ it('counts disabled tests in a suite', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, DISABLED_SPEC_INFO, PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['disabled']).toBe(1); ++ }); ++ ++ it('counts errored tests in a suite', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, ERROR_SPEC_INFO, PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['errors']).toBe(1); ++ }); ++ ++ it('counts failed tests in a suite', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, FAILING_SPEC_INFO, PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['failures']).toBe(1); ++ }); ++ ++ it('counts skipped tests in a suite', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, PENDING_SPEC_INFO, PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.attrs['skipped']).toBe(1); ++ }); ++ ++ it('timestamps a suite', function () { ++ runSuite(SUITE_INFO, []); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(() => Date.parse(testsuite.attrs['timestamp'])).not.toThrow(); ++ }); ++ ++ it('flattens nested suites', function () { ++ reporter.suiteStarted(SUITE_INFO); ++ [PASSING_SPEC_INFO, PASSING_SPEC_INFO].forEach(runSpec); ++ reporter.suiteStarted(NESTED_SUITE_INFO); ++ [NESTED_PASSING_SPEC_INFO, NESTED_PASSING_SPEC_INFO].forEach(runSpec); ++ reporter.suiteDone(NESTED_SUITE_INFO); ++ runSpec(PASSING_SPEC_INFO); ++ reporter.suiteDone(SUITE_INFO); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const suite1 = findSuite(tree, 0); ++ const suite2 = findSuite(tree, 1); ++ expect(suite1.attrs['tests']).toBe(3); ++ expect(suite2.attrs['tests']).toBe(2); ++ }); ++ ++ it('reports exceptions in afterAll() as errors in a separate suite', function () { ++ runSuite(FAILED_SUITE_INFO, [PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const afterAllSuite = findSuite(tree, 1); ++ expect(afterAllSuite.attrs['tests']).toBe(1); ++ expect(afterAllSuite.attrs['errors']).toBe(1); ++ }); ++ ++ it('reports an error in afterAll() as a test case', function () { ++ runSuite(FAILED_SUITE_INFO, [PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const afterAllSuite = findSuite(tree, 1); ++ expect(afterAllSuite.children[0]).toEqual(jasmine.objectContaining({ ++ name: 'testcase', ++ attrs: jasmine.any(Object), ++ children: [jasmine.objectContaining({ ++ name: 'error', ++ attrs: jasmine.objectContaining({ ++ message: 'Some error', ++ type: 'Error', ++ }), ++ text: 'file.js:113\nfile.js:72\nfile.js:17\n', ++ })], ++ })); ++ }); ++ ++ it('adds the environment in a element', function () { ++ GLib.setenv('JASMINE_TESTS_BOGUS_VARIABLE', 'surprise', true); ++ reporter.jasmineStarted(); // restart ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const [properties] = tree.children.filter(child => child.name === 'properties'); ++ expect(properties.children).toContain(jasmine.objectContaining({ ++ name: 'property', ++ attrs: { ++ name: 'JASMINE_TESTS_BOGUS_VARIABLE', ++ value: 'surprise', ++ }, ++ })); ++ }); ++ ++ it('reports the total number of assertions', function () { ++ runSuite(SUITE_INFO, [PASSING_SPEC_INFO, ERROR_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const testsuite = findSuite(tree, 0); ++ expect(testsuite.children[0].attrs['assertions']).toBe(2); ++ expect(testsuite.children[1].attrs['assertions']).toBe(2); ++ }); ++ ++ it('reports the total number of assertions in an afterAll() suite', function () { ++ runSuite(FAILED_SUITE_INFO, [PASSING_SPEC_INFO]); ++ reporter.jasmineDone(); ++ ++ const tree = JSON.parse(out.getOutput()); ++ const afterAllSuite = findSuite(tree, 1); ++ expect(afterAllSuite.children[0].attrs['assertions']).toBe(1); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/optionsSpec.js index 000000000,000000000..25fbf3258 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/optionsSpec.js @@@ -1,0 -1,0 +1,47 @@@ ++// FIXME: the argument parser should be refactored into something more general ++// so that the ARGS object in options.js isn't hardcoded. ++ ++import * as Options from '../src/options.js'; ++ ++describe('Argument parser', function () { ++ it('stores the given value for a "store" argument', function () { ++ const [files, namespace] = Options.parseOptions(['--junit', 'file.txt']); ++ expect(files).toEqual([]); ++ expect(namespace['junit']).toEqual('file.txt'); ++ }); ++ ++ it('stores the value from "const" for a "store" argument if none given', function () { ++ const [files, namespace] = Options.parseOptions(['--junit']); ++ expect(files).toEqual([]); ++ expect(namespace['junit']).toEqual('report.xml'); ++ }); ++ ++ it('stores values in the order they are given on the command line', function () { ++ const [, namespace] = Options.parseOptions(['--no-color', '--color']); ++ expect(namespace['color']).toBe(true); ++ }); ++ ++ it('stores the given value for an "append" argument', function () { ++ const [, namespace] = Options.parseOptions(['--exclude', 'file.js']); ++ expect(namespace['exclude']).toEqual(['file.js']); ++ }); ++ ++ it('stores multiple values for an "append" argument appearing multiple times', function () { ++ const [, namespace] = Options.parseOptions([ ++ '--exclude', 'file.js', ++ '--exclude', 'file2.js', ++ ]); ++ expect(namespace['exclude']).toEqual(['file.js', 'file2.js']); ++ }); ++ ++ it('does not modify the list of arguments passed in', function () { ++ const args = ['arg1', 'arg2', 'arg3']; ++ Options.parseOptions(args); ++ expect(args.length).toBe(3); ++ }); ++ ++ it('does not treat a short option as a file', function () { ++ const [files] = Options.parseOptions(['-c', 'file.js']); ++ expect(files).toEqual(['file.js']); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/tapReporterSpec.js index 000000000,000000000..ea90afc99 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/tapReporterSpec.js @@@ -1,0 -1,0 +1,251 @@@ ++import * as TapReporter from '../src/tapReporter.js'; ++ ++describe('The TAP reporter', function () { ++ let out, reporter; ++ ++ beforeEach(function () { ++ out = (function () { ++ let output = ''; ++ return { ++ print(str) { ++ output += str; ++ }, ++ getOutput() { ++ return output; ++ }, ++ clear() { ++ output = ''; ++ }, ++ }; ++ })(); ++ ++ reporter = new TapReporter.TapReporter({ ++ print: out.print, ++ }); ++ }); ++ ++ it('outputs a test plan', function () { ++ reporter.jasmineStarted({totalSpecsDefined: 1}); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'passed', ++ }); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1../); ++ }); ++ ++ it('includes the total number of specs in the test plan', function () { ++ reporter.jasmineStarted({totalSpecsDefined: 2}); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'passed', ++ }); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'bar', ++ status: 'passed', ++ }); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1..2/); ++ }); ++ ++ it('outputs an empty test plan if there were no specs', function () { ++ reporter.jasmineStarted({totalSpecsDefined: 0}); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1..0/); ++ }); ++ ++ it('outputs a line starting with "ok" for a passing spec', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'passed', ++ }); ++ expect(out.getOutput()).toMatch(/^ok/); ++ }); ++ ++ it('outputs a line starting with "not ok" for a failing spec', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'failed', ++ }); ++ expect(out.getOutput()).toMatch(/^not ok/); ++ }); ++ ++ it('outputs an "ok" line plus a skip directive for a pending spec', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'pending', ++ }); ++ expect(out.getOutput()).toMatch(/^ok/); ++ expect(out.getOutput()).toMatch(/# skip/i); ++ }); ++ ++ it('reports the reason for a pending spec, if given', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'pending', ++ pendingReason: 'because I said so', ++ }); ++ expect(out.getOutput()).toMatch('because I said so'); ++ }); ++ ++ it('outputs an "ok" line plus a skip directive for a disabled spec', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'disabled', ++ }); ++ expect(out.getOutput()).toMatch(/^ok/); ++ expect(out.getOutput()).toMatch(/# skip/i); ++ }); ++ ++ it('outputs a sequence number after the result', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'passed', ++ }); ++ expect(out.getOutput()).toMatch(/^ok 1/); ++ out.clear(); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ fullName: 'bar', ++ status: 'failed', ++ }); ++ expect(out.getOutput()).toMatch(/^not ok 2/); ++ }); ++ ++ it('outputs the name of the spec on the test line', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ status: 'passed', ++ fullName: 'A passing spec', ++ }); ++ expect(out.getOutput()).toMatch(/^ok.*A passing spec/); ++ out.clear(); ++ reporter.specStarted({}); ++ reporter.specDone({ ++ status: 'failed', ++ fullName: 'A failing spec', ++ }); ++ expect(out.getOutput()).toMatch(/^not ok.*A failing spec/); ++ }); ++ ++ it('does not let the name start with a digit', function () { ++ reporter.specStarted({}); ++ reporter.specDone({ ++ status: 'passed', ++ fullName: '3 careless programmers wrote this', ++ }); ++ expect(out.getOutput()).toMatch(/^ok 1/); ++ expect(out.getOutput()).not.toMatch(/^ok 1\s*[0-9]+/); ++ }); ++ ++ describe('on failure', function () { ++ beforeEach(function () { ++ reporter.specStarted({}); ++ out.clear(); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'failed', ++ failedExpectations: [ ++ { ++ message: 'Expected the earth and the sky.', ++ stack: 'line 1\nline 2\nline 3', ++ }, ++ { ++ message: 'Expectations exceeded.', ++ stack: 'line 4\nline 5', ++ }, ++ ], ++ }); ++ }); ++ ++ it('outputs messages on the test line', function () { ++ const output = out.getOutput(); ++ const [testLine] = output.split('\n'); ++ expect(testLine).toMatch(/^not ok.*Expected the earth and the sky\./); ++ expect(testLine).toMatch(/^not ok.*Expectations exceeded\./); ++ }); ++ ++ it('outputs messages and stack traces as diagnostic lines', function () { ++ const diagnostics = out.getOutput().split('\n').slice(1); ++ expect(diagnostics).toMatch(/^#.*Expected the earth and the sky\./m); ++ expect(diagnostics).toMatch(/^#.*Expectations exceeded\./m); ++ expect(diagnostics).toMatch(/^#.*line 1/m); ++ expect(diagnostics).toMatch(/^#.*line 2/m); ++ expect(diagnostics).toMatch(/^#.*line 3/m); ++ expect(diagnostics).toMatch(/^#.*line 4/m); ++ expect(diagnostics).toMatch(/^#.*line 5/m); ++ }); ++ }); ++ ++ describe('on failure with newlines', function () { ++ beforeEach(function () { ++ reporter.specStarted({}); ++ out.clear(); ++ reporter.specDone({ ++ fullName: 'foo', ++ status: 'failed', ++ failedExpectations: [{ ++ message: 'A message\non two lines', ++ stack: '', ++ }], ++ }); ++ }); ++ ++ it('prints no newlines on the test line', function () { ++ const [testLine] = out.getOutput().split('\n'); ++ expect(testLine).toMatch(/^not ok.*A message.*on two lines/); ++ }); ++ ++ it('prints no newlines in the diagnostics', function () { ++ const diagnostics = out.getOutput().split('\n').slice(1); ++ expect(diagnostics).not.toMatch(/^[^#]/); ++ }); ++ }); ++ ++ it('reports suites starting as diagnostic lines', function () { ++ reporter.suiteStarted({ ++ fullName: 'A suite', ++ }); ++ expect(out.getOutput()).toMatch(/^#.*A suite/); ++ }); ++ ++ it('reports suites finishing successfully as diagnostic lines', function () { ++ reporter.suiteDone({ ++ status: 'passed', ++ fullName: 'A suite', ++ failedExpectations: [], ++ }); ++ expect(out.getOutput()).toMatch(/^#.*A suite/); ++ }); ++ ++ it('reports suites with failing specs as diagnostic lines', function () { ++ reporter.suiteDone({ ++ status: 'failed', ++ fullName: 'A suite', ++ failedExpectations: [], ++ }); ++ expect(out.getOutput()).toMatch(/^#.*A suite/); ++ }); ++ ++ it('reports failures in afterAll as an extra failure', function () { ++ reporter.suiteDone({ ++ status: 'failed', ++ fullName: 'A suite', ++ failedExpectations: [{message: 'An afterAll exception'}], ++ }); ++ reporter.jasmineDone(); ++ expect(out.getOutput()).toMatch(/^not ok.*An afterAll exception/m); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/timerSpec.js index 000000000,000000000..28756e888 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/timerSpec.js @@@ -1,0 -1,0 +1,9 @@@ ++import * as Timer from '../src/timer.js'; ++ ++describe('The default timer', function () { ++ it('stops timing when elapsed() is called', function () { ++ const timer = Timer.createDefaultTimer(); ++ timer.start(); ++ expect(timer.elapsed()).toEqual(timer.elapsed()); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/utils.js index 000000000,000000000..39b4d1ed6 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/utils.js @@@ -1,0 -1,0 +1,3 @@@ ++function add(a, b) { ++ return a + b; ++} diff --cc subprojects/jasmine-gjs/test/utilsSpec.js index 000000000,000000000..3d84b5185 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/utilsSpec.js @@@ -1,0 -1,0 +1,20 @@@ ++import {indenter} from '../src/utils.js'; ++ ++describe('Indent', function () { ++ it('prepends spaces to a string', function () { ++ expect(indenter.indent('foo', 4)).toEqual(' foo'); ++ }); ++ ++ it('prepends spaces to each line in a string', function () { ++ expect(indenter.indent('a\nb\nc', 4)).toEqual(' a\n b\n c'); ++ }); ++ ++ it('does not indent an extra blank line at the end of the string', function () { ++ expect(indenter.indent('a\nb\n', 4)).toEqual(' a\n b\n'); ++ }); ++ ++ it('handles zero spaces', function () { ++ expect(indenter.indent('foo', 0)).toEqual('foo'); ++ expect(indenter.indent('a\nb\nc', 0)).toEqual('a\nb\nc'); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/verboseReporterSpec.js index 000000000,000000000..91415d4d0 new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/verboseReporterSpec.js @@@ -1,0 -1,0 +1,307 @@@ ++import * as VerboseReporter from '../src/verboseReporter.js'; ++import {indenter} from '../src/utils.js'; ++ ++describe('Verbose console reporter', function () { ++ let out, reporter, timerSpy, timerSpies; ++ ++ beforeEach(function () { ++ out = (function () { ++ let output = ''; ++ return { ++ print(str) { ++ output += str; ++ }, ++ getOutput() { ++ return output; ++ }, ++ clear() { ++ output = ''; ++ }, ++ }; ++ })(); ++ ++ timerSpies = {}; ++ timerSpy = id => { ++ timerSpies[id] = jasmine.createSpyObj('timer', ['start', 'elapsed']); ++ return timerSpies[id]; ++ }; ++ ++ reporter = new VerboseReporter.VerboseReporter({ ++ print: out.print, ++ show_colors: false, ++ timerFactory: timerSpy, ++ }); ++ ++ // disable indentation for test purposes ++ spyOn(indenter, 'indent').and.callFake(str => str); ++ }); ++ ++ it('reports that the suite has started to the console', function () { ++ reporter.jasmineStarted(); ++ expect(out.getOutput()).toEqual('Started\n\n'); ++ }); ++ ++ it('reports a passing spec with a checkmark', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'passed', ++ description: 'A passing spec', ++ }); ++ expect(out.getOutput()).toEqual('✓ A passing spec\n'); ++ }); ++ ++ it('reports a disabled spec with an "x"', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'disabled', ++ description: 'A disabled spec', ++ }); ++ expect(out.getOutput()).toEqual('x A disabled spec\n'); ++ }); ++ ++ it('reports a failing spec with a number', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'failed', ++ description: 'A failing spec', ++ }); ++ expect(out.getOutput()).toEqual('1) A failing spec\n'); ++ }); ++ ++ it('reports a failing spec with the number of that failure in sequence', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'failed', ++ description: 'A failing spec', ++ }); ++ out.clear(); ++ reporter.specStarted({id: 'bar'}); ++ reporter.specDone({ ++ id: 'bar', ++ status: 'failed', ++ description: 'Another failing spec', ++ }); ++ expect(out.getOutput()).toEqual('2) Another failing spec\n'); ++ }); ++ ++ it('reports a pending spec as a dash', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'pending', ++ description: 'A pending spec', ++ }); ++ expect(out.getOutput()).toEqual('- A pending spec\n'); ++ }); ++ ++ it('reports a summary when done', function () { ++ reporter.jasmineStarted(); ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ description: 'A spec', ++ status: 'passed', ++ }); ++ reporter.specStarted({id: 'bar'}); ++ reporter.specDone({ ++ id: 'bar', ++ description: 'A spec', ++ status: 'pending', ++ }); ++ reporter.specStarted({id: 'baz'}); ++ reporter.specDone({ ++ id: 'baz', ++ status: 'failed', ++ description: 'with a failing spec', ++ fullName: 'A suite with a failing spec', ++ failedExpectations: [{ ++ passed: false, ++ message: 'Expected true to be false.', ++ expected: false, ++ actual: true, ++ stack: 'fakeStack\nfakeStack', ++ }], ++ }); ++ ++ out.clear(); ++ ++ timerSpies['main'].elapsed.and.returnValue(100); ++ ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1 passing \(0.1 s\)/); ++ expect(out.getOutput()).toMatch(/1 pending/); ++ expect(out.getOutput()).toMatch(/1 failing/); ++ }); ++ ++ it('reports a summary when done even if there are no specs', function () { ++ reporter.jasmineStarted(); ++ timerSpies['main'].elapsed.and.returnValue(100); ++ out.clear(); ++ reporter.jasmineDone(); ++ expect(out.getOutput()).toMatch(/0 passing \(0.1 s\)/); ++ }); ++ ++ it('reports a summary when done that includes the failed spec number before the full name of a failing spec', function () { ++ reporter.jasmineStarted(); ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ description: 'A spec', ++ status: 'passed', ++ }); ++ reporter.specStarted({id: 'bar'}); ++ reporter.specDone({ ++ id: 'bar', ++ status: 'failed', ++ description: 'with a failing spec', ++ fullName: 'A suite with a failing spec', ++ failedExpectations: [{ ++ passed: false, ++ message: 'Expected true to be false.', ++ expected: false, ++ actual: true, ++ stack: 'fakeStack\nfakeStack', ++ }], ++ }); ++ ++ out.clear(); ++ ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/1\) A suite with a failing spec/); ++ }); ++ ++ it('prints a warning when a spec takes over 40 ms', function () { ++ reporter.specStarted({id: 'foo'}); ++ timerSpies['spec:foo'].elapsed.and.returnValue(50); ++ reporter.specDone({ ++ id: 'foo', ++ description: 'A spec', ++ status: 'passed', ++ }); ++ ++ expect(out.getOutput()).toMatch('(50 ms)'); ++ }); ++ ++ it('prints the reason for a pending spec', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'pending', ++ description: 'a pending spec', ++ pendingReason: 'it was not ready', ++ }); ++ expect(out.getOutput()).toMatch('(it was not ready)'); ++ }); ++ ++ describe('with color', function () { ++ beforeEach(function () { ++ reporter = new VerboseReporter.VerboseReporter({ ++ print: out.print, ++ showColors: true, ++ timerFactory: timerSpy, ++ }); ++ }); ++ ++ it('reports that the suite has started to the console', function () { ++ reporter.jasmineStarted(); ++ expect(out.getOutput()).toEqual('Started\n\n'); ++ }); ++ ++ it('reports a passing spec with a checkmark', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'passed', ++ description: 'A passing spec', ++ }); ++ expect(out.getOutput()).toEqual('\x1b[32m✓\x1b[0m A passing spec\n'); ++ }); ++ ++ it('reports a disabled spec with an "x"', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'disabled', ++ description: 'A disabled spec', ++ }); ++ expect(out.getOutput()).toEqual('x A disabled spec\n'); ++ }); ++ ++ it('reports a failing spec with a number', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'failed', ++ description: 'A failing spec', ++ }); ++ expect(out.getOutput()).toEqual('\x1b[31m1)\x1b[0m A failing spec\n'); ++ }); ++ ++ it('reports a disabled suite with "disabled"', function () { ++ reporter.suiteDone({ ++ status: 'disabled', ++ description: 'A disabled suite', ++ }); ++ expect(out.getOutput()).toEqual('\x1b[33m(disabled)\x1b[0m\n'); ++ }); ++ ++ it('prints a mild warning when a spec takes over 40 ms', function () { ++ reporter.specStarted({id: 'foo'}); ++ timerSpies['spec:foo'].elapsed.and.returnValue(50); ++ reporter.specDone({ ++ id: 'foo', ++ description: 'A spec', ++ status: 'passed', ++ }); ++ ++ // eslint-disable-next-line no-control-regex ++ expect(out.getOutput()).toMatch(/\x1b\[33m\(50 ms\)\x1b\[0m/); ++ }); ++ ++ it('prints a loud warning when a spec takes over 75 ms', function () { ++ reporter.specStarted({id: 'foo'}); ++ timerSpies['spec:foo'].elapsed.and.returnValue(80); ++ reporter.specDone({ ++ id: 'foo', ++ description: 'A spec', ++ status: 'passed', ++ }); ++ ++ // eslint-disable-next-line no-control-regex ++ expect(out.getOutput()).toMatch(/\x1b\[31m\(80 ms\)\x1b\[0m/); ++ }); ++ ++ it('prints a pending reason in yellow', function () { ++ reporter.specStarted({id: 'foo'}); ++ reporter.specDone({ ++ id: 'foo', ++ status: 'pending', ++ description: 'a pending spec', ++ pendingReason: 'it was not ready', ++ }); ++ // eslint-disable-next-line no-control-regex ++ expect(out.getOutput()).toMatch(/\x1b\[33m\(it was not ready\)\x1b\[0m/); ++ }); ++ }); ++ ++ it('displays all afterAll exceptions', function () { ++ reporter.suiteDone({ ++ status: 'failed', ++ failedExpectations: [{message: 'After All Exception'}], ++ }); ++ reporter.suiteDone({ ++ status: 'failed', ++ failedExpectations: [{message: 'Some Other Exception'}], ++ }); ++ reporter.jasmineDone(); ++ ++ expect(out.getOutput()).toMatch(/After All Exception/); ++ expect(out.getOutput()).toMatch(/Some Other Exception/); ++ }); ++}); diff --cc subprojects/jasmine-gjs/test/xmlWriterSpec.js index 000000000,000000000..de8bd255a new file mode 100644 --- /dev/null +++ b/subprojects/jasmine-gjs/test/xmlWriterSpec.js @@@ -1,0 -1,0 +1,98 @@@ ++import * as XMLWriter from '../src/xmlWriter.js'; ++ ++describe('XML writer', function () { ++ let node; ++ ++ beforeEach(function () { ++ node = new XMLWriter.Node('node'); ++ }); ++ ++ it('prints a doctype declaration', function () { ++ expect(node.toString()).toMatch(/^<\?xml version=(['"])1\.0\1 encoding=(['"])UTF-8\2\?>/); ++ }); ++ ++ it('prints a single empty node', function () { ++ expect(node.toString()).toMatch(''); ++ }); ++ ++ it('prints a single node with an attribute', function () { ++ node.attrs = { ++ attr: 'value', ++ }; ++ expect(node.toString()).toMatch(//); ++ }); ++ ++ it('separates attributes with a space', function () { ++ node.attrs = { ++ attr: 'value', ++ key: 'something', ++ }; ++ expect(node.toString()).toMatch(//); ++ }); ++ ++ it('escapes attribute values', function () { ++ node.attrs = { ++ attr: '"<>&\'', ++ }; ++ expect(node.toString()).toMatch(//); ++ }); ++ ++ it('prints child nodes', function () { ++ node.children.push(new XMLWriter.Node('child')); ++ expect(node.toString()).toMatch(/\s*\s*<\/node>/); ++ }); ++ ++ it('prints child nodes in order', function () { ++ node.children = [ ++ new XMLWriter.Node('child-one'), ++ new XMLWriter.Node('child-two'), ++ new XMLWriter.Node('child-three'), ++ ]; ++ expect(node.toString()).toMatch(/\s*\s*\s*\s*<\/node>/); ++ }); ++ ++ it('prints child nodes indented', function () { ++ node.children.push(new XMLWriter.Node('child')); ++ expect(node.toString()).toMatch('\n \n\n'); ++ }); ++ ++ it('prints multiple levels of indentation', function () { ++ const child = new XMLWriter.Node('child'); ++ child.children.push(new XMLWriter.Node('descendant')); ++ node.children.push(child); ++ const output = node.toString(); ++ expect(output).toMatch('\n\n'); ++ expect(output).toMatch('\n \n'); ++ expect(output).toMatch('\n \n'); ++ expect(output).toMatch('\n \n'); ++ expect(output).toMatch('\n\n'); ++ }); ++ ++ it('prints text content', function () { ++ node.text = 'A very fine day'; ++ expect(node.toString()).toMatch(/\s*A very fine day\s*<\/node>/); ++ }); ++ ++ it('prints text content indented', function () { ++ node.text = 'A very fine day'; ++ expect(node.toString()).toMatch('\n A very fine day\n'); ++ }); ++ ++ it('trims text content', function () { ++ node.text = ' \nA very fine day\n '; ++ expect(node.toString()).toMatch('\n A very fine day\n'); ++ }); ++ ++ it('escapes text content', function () { ++ node.text = '"<>&\''; ++ expect(node.toString()).toMatch('"<>&''); ++ }); ++ ++ it('prints child nodes and text content', function () { ++ node.children.push(new XMLWriter.Node('child')); ++ node.text = 'Other content'; ++ const output = node.toString(); ++ expect(output).toMatch(''); ++ expect(output).toMatch('Other content'); ++ }); ++});